SQLAlchemy ORM - Eifriges Laden
Eifrige Last reduziert die Anzahl der Abfragen. SQLAlchemy bietet eifrige Ladefunktionen, die über Abfrageoptionen aufgerufen werden und der Abfrage zusätzliche Anweisungen geben. Diese Optionen bestimmen, wie verschiedene Attribute über die Query.options () -Methode geladen werden.
Unterabfrage laden
Wir möchten, dass Customer.invoices eifrig geladen werden. Die Option orm.subqueryload () gibt eine zweite SELECT-Anweisung aus, die die Sammlungen, die den gerade geladenen Ergebnissen zugeordnet sind, vollständig lädt. Der Name "Unterabfrage" bewirkt, dass die SELECT-Anweisung direkt über die wiederverwendete Abfrage erstellt und als Unterabfrage in eine SELECT für die zugehörige Tabelle eingebettet wird.
from sqlalchemy.orm import subqueryload
c1 = session.query(Customer).options(subqueryload(Customer.invoices)).filter_by(name = 'Govind Pant').one()
Dies führt zu den folgenden zwei SQL-Ausdrücken:
SELECT customers.id
AS customers_id, customers.name
AS customers_name, customers.address
AS customers_address, customers.email
AS customers_email
FROM customers
WHERE customers.name = ?
('Govind Pant',)
SELECT invoices.id
AS invoices_id, invoices.custid
AS invoices_custid, invoices.invno
AS invoices_invno, invoices.amount
AS invoices_amount, anon_1.customers_id
AS anon_1_customers_id
FROM (
SELECT customers.id
AS customers_id
FROM customers
WHERE customers.name = ?)
AS anon_1
JOIN invoices
ON anon_1.customers_id = invoices.custid
ORDER BY anon_1.customers_id, invoices.id 2018-06-25 18:24:47,479
INFO sqlalchemy.engine.base.Engine ('Govind Pant',)
Um auf die Daten aus zwei Tabellen zuzugreifen, können wir das folgende Programm verwenden:
print (c1.name, c1.address, c1.email)
for x in c1.invoices:
print ("Invoice no : {}, Amount : {}".format(x.invno, x.amount))
Die Ausgabe des obigen Programms ist wie folgt:
Govind Pant Gulmandi Aurangabad [email protected]
Invoice no : 3, Amount : 10000
Invoice no : 4, Amount : 5000
Verbundenes Laden
Die andere Funktion heißt orm.joinedload (). Dies gibt einen LEFT OUTER JOIN aus. Das Hauptobjekt sowie das zugehörige Objekt oder die zugehörige Sammlung werden in einem Schritt geladen.
from sqlalchemy.orm import joinedload
c1 = session.query(Customer).options(joinedload(Customer.invoices)).filter_by(name='Govind Pant').one()
Dies gibt den folgenden Ausdruck aus, der dieselbe Ausgabe wie oben ergibt -
SELECT customers.id
AS customers_id, customers.name
AS customers_name, customers.address
AS customers_address, customers.email
AS customers_email, invoices_1.id
AS invoices_1_id, invoices_1.custid
AS invoices_1_custid, invoices_1.invno
AS invoices_1_invno, invoices_1.amount
AS invoices_1_amount
FROM customers
LEFT OUTER JOIN invoices
AS invoices_1
ON customers.id = invoices_1.custid
WHERE customers.name = ? ORDER BY invoices_1.id
('Govind Pant',)
Der OUTER JOIN führte zu zwei Zeilen, gibt jedoch eine Instanz des Kunden zurück. Dies liegt daran, dass Query eine auf der Objektidentität basierende "Eindeutigkeits" -Strategie auf die zurückgegebenen Entitäten anwendet. Verbundenes eifriges Laden kann angewendet werden, ohne die Abfrageergebnisse zu beeinflussen.
Subqueryload () eignet sich besser zum Laden verwandter Sammlungen, während joinload () besser für die Beziehung zwischen vielen Personen geeignet ist.