SQLAlchemy ORM - Chargement hâtif

Une charge hâtive réduit le nombre de requêtes. SQLAlchemy propose des fonctions de chargement rapide appelées via des options de requête qui donnent des instructions supplémentaires à la requête. Ces options déterminent comment charger divers attributs via la méthode Query.options ().

Charge de sous-requête

Nous voulons que Customer.invoices se charge avec empressement. L'option orm.subqueryload () donne une seconde instruction SELECT qui charge complètement les collections associées aux résultats qui viennent d'être chargés. Le nom «sous-requête» provoque la construction de l'instruction SELECT directement via la requête réutilisée et incorporée en tant que sous-requête dans un SELECT sur la table associée.

from sqlalchemy.orm import subqueryload
c1 = session.query(Customer).options(subqueryload(Customer.invoices)).filter_by(name = 'Govind Pant').one()

Il en résulte les deux expressions SQL suivantes -

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',)

Pour accéder aux données de deux tables, nous pouvons utiliser le programme ci-dessous -

print (c1.name, c1.address, c1.email)

for x in c1.invoices:
   print ("Invoice no : {}, Amount : {}".format(x.invno, x.amount))

La sortie du programme ci-dessus est la suivante -

Govind Pant Gulmandi Aurangabad [email protected]
Invoice no : 3, Amount : 10000
Invoice no : 4, Amount : 5000

Charge jointe

L'autre fonction s'appelle orm.joinedload (). Cela émet une JOINTURE EXTÉRIEURE GAUCHE. L'objet principal ainsi que l'objet ou la collection associé sont chargés en une seule étape.

from sqlalchemy.orm import joinedload
c1 = session.query(Customer).options(joinedload(Customer.invoices)).filter_by(name='Govind Pant').one()

Cela émet l'expression suivante donnant la même sortie que ci-dessus -

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',)

L'OUTER JOIN a donné deux lignes, mais il renvoie une instance de Customer. En effet, Query applique une stratégie «unique», basée sur l'identité de l'objet, aux entités renvoyées. Le chargement hâtif joint peut être appliqué sans affecter les résultats de la requête.

Le subqueryload () est plus approprié pour le chargement des collections associées tandis que joinsload () est mieux adapté pour la relation plusieurs-à-un.