SQLAlchemy ORM - Zachłanne ładowanie
Chętne ładowanie zmniejsza liczbę zapytań. SQLAlchemy oferuje funkcje szybkiego ładowania wywoływane przez opcje zapytania, które dają dodatkowe instrukcje zapytaniu. Te opcje określają sposób ładowania różnych atrybutów za pomocą metody Query.options ().
Ładowanie podzapytania
Chcemy, aby faktury Klienta były szybko ładowane. Opcja orm.subqueryload () daje drugą instrukcję SELECT, która w pełni ładuje kolekcje powiązane z właśnie załadowanymi wynikami. Nazwa „podzapytanie” powoduje, że instrukcja SELECT jest konstruowana bezpośrednio przez zapytanie ponownie użyte i osadzone jako podzapytanie w SELECT względem powiązanej tabeli.
from sqlalchemy.orm import subqueryload
c1 = session.query(Customer).options(subqueryload(Customer.invoices)).filter_by(name = 'Govind Pant').one()
Powoduje to dwa następujące wyrażenia SQL -
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',)
Aby uzyskać dostęp do danych z dwóch tabel, możemy skorzystać z poniższego programu -
print (c1.name, c1.address, c1.email)
for x in c1.invoices:
print ("Invoice no : {}, Amount : {}".format(x.invno, x.amount))
Wynik powyższego programu jest następujący -
Govind Pant Gulmandi Aurangabad [email protected]
Invoice no : 3, Amount : 10000
Invoice no : 4, Amount : 5000
Połączone obciążenie
Druga funkcja nazywa się orm.joinedload (). To emituje LEWE POŁĄCZENIE ZEWNĘTRZNE. Obiekt wiodący oraz powiązany obiekt lub kolekcja są ładowane w jednym kroku.
from sqlalchemy.orm import joinedload
c1 = session.query(Customer).options(joinedload(Customer.invoices)).filter_by(name='Govind Pant').one()
To emituje następujące wyrażenie dające taki sam wynik jak powyżej -
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',)
ZEWNĘTRZNE JOIN spowodowało powstanie dwóch wierszy, ale zwraca jedno wystąpienie klienta. Dzieje się tak, ponieważ Query stosuje strategię „unikatową”, opartą na tożsamości obiektu, do zwracanych jednostek. Dołączone przyspieszone ładowanie można zastosować bez wpływu na wyniki zapytania.
Subqueryload () jest bardziej odpowiednia do ładowania powiązanych kolekcji, podczas gdy joinload () lepiej nadaje się do relacji wiele do jednego.