2016-11-21 2 views
1

J'ai une configuration de page Web de pyramide. L'un des points de vue fait quelque chose comme ceci: -Requêtes SQLAlchemy - quand sont-elles exécutées?

sql_list = do_a_query() 
handle_a_post_request(request) 
return dict(sql_list=sql_list) 

def do_a_query(): 
    request.db.query(WhatIAmLookingFor) 

Le (Mako, mais je pense que c'est hors de propos) modèle gère l'affichage puis ma page Web sur la base des données sql_list.

Dans la fonction handle_a_post_request, je modifie la session (et exécute commit()) en fonction de la demande de publication. Ces modifications apparaissent dans la page résultante, ce qui me suggère que la requête elle-même "s'exécute" ou s'exécute quand elle est appelée dans mon modèle. Depuis que j'utilise mako l'appel est fait en utilisant: -

% for row in sql_list: 
<tr> 
    <td> ${row[0]} </td> 
    <td> ${row[1]} </td> 
    <td> ${row[2]} </td> 
</tr> 

Ma conclusion est-elle correcte? Quand exactement une requête sqlalchemy est-elle «actualisée», de sorte que les modifications apportées à la session après ce point n'apparaissent plus dans le «résultat» de la requête? Ou est-ce que ma compréhension est fondamentalement erronée quelque part? Ce qui me préoccupe, c'est qu'à l'avenir, une modification de la fonction do_a_query() (par exemple, l'itération de ses résultats pour un pré-traitement avant l'affichage) changera le comportement de ma page Web. Bien sûr, la «bonne» réponse est simplement de déplacer handle_a_post_request() plus tôt, mais j'aimerais bien comprendre ce qui se passe en premier.

+0

Je pense que vous pourriez être en train de courir dans '' autoflush'', jetez un oeil à ceci: http://stackoverflow.com/questions/4201455/sqlalchemy-whats-the-difference-between-flush-and-commit –

+0

Non, certainement pas cet ensemble. –

Répondre

1

Une requête est généralement exécutée lorsque vous effectuez une itération sur une instance Query. Query.all() est une méthode pratique de création d'une liste à partir de l'itérateur Query. (Les requêtes sont également exécutées automatiquement lorsque vous tentez de charger des attributs expirés, mais pour les besoins de cette réponse, ignorons ceux-ci.)

Il est important de noter qu'à aucun moment, les modifications de la session ne sont invisibles. Par défaut, SQLAlchemy garantit que la session est vidée à des heures appropriées de sorte que les modifications apportées à la session soient répercutées sur la requête suivante.

Dans votre cas, vous devez renvoyer le résultat de .all() au do_a_query() au lieu de renvoyer la requête elle-même.

+0

Merci, donc tout ce qui commence à parcourir l'instance 'Query' va exécuter la requête? Que faire si je l'itère deux fois (et qu'il se passe quelque chose entre les deux itérations)? –

+0

@ NgOon-Ee Ensuite, il va exécuter deux requêtes. Si vous modifiez quelque chose dans la session (ajoutez une instance, supprimez une instance, mettez à jour une instance), SQLAlchemy effectuera par défaut les modifications nécessaires avant d'exécuter la seconde requête. Si * une autre transaction * change quelque chose, alors selon le niveau d'isolement, vous pouvez ou ne pouvez pas voir les changements. – univerio

+0

Merci. Donc, mon erreur ici est d'imaginer que l'instance 'Query' est en fait un ensemble de résultats. Merci pour votre explication rapide, précise et exacte. –