SQLAlchemy: Création de vs la Réutilisation d'une Session
Juste une petite question: SQLAlchemy parle appel sessionmaker()
une fois, mais l'appel de la résultante Session()
classe à chaque fois que vous avez besoin de parler à votre base de données. Pour moi, cela signifie la seconde, je ferais de mon premier session.add(x)
ou quelque chose de similaire, je voudrais tout d'abord faire
from project import Session
session = Session()
Ce que j'ai fait jusqu'à maintenant a été de faire l'appel session = Session()
dans mon modèle une fois et puis toujours à l'importation de la même session, n'importe où dans mon application. Puisque c'est une web-applications ce serait généralement dire la même (un point de vue est exécutée).
Mais où est la différence? Quel est l'inconvénient de l'utilisation d'une séance tous les temps contre de l'utiliser pour ma base de données des trucs jusqu'à ce que ma fonction est effectuée, puis en créer un nouveau la prochaine fois que je veux parler à mon DB?
- Je obtenir que si j'utilise plusieurs threads, chacun doit obtenir leur propre session. Mais à l'aide de scoped_session()
, je l'ai déjà assurez-vous que le problème n'existe pas, puis-je?
Veuillez préciser si l'une de mes hypothèses sont fausses.
Vous devez vous connecter pour publier un commentaire.
sessionmaker()
est une usine, il est là pour les encourager à placer des options de configuration pour la création de nouveauxSession
objets dans un seul endroit. Il est facultatif, en ce que vous pourrait tout aussi bien appelerSession(bind=engine, expire_on_commit=False)
à tout moment vous avez besoin d'un nouveauSession
, sauf que son détaillé et redondants, et j'ai voulu arrêter la prolifération de la petite échelle "aides" que chacun a abordé la question de cette redondance dans certains de nouvelles et plus de confusion.Donc
sessionmaker()
est juste un outil pour vous aider à créerSession
objets lorsque vous en avez besoin.Prochaine partie. Je pense que la question est, quelle est la différence entre faire un nouveau
Session()
à différents points plutôt qu'à l'aide d'un tout le chemin à travers. La réponse, pas très bien.Session
est un conteneur pour tous les objets que vous avez mis en elle, et puis elle conserve également la trace d'une transaction ouverte. Au moment de l'appelrollback()
oucommit()
, la transaction est terminée, et leSession
a pas de connexion à la base de données jusqu'à ce qu'il est appelé à émettre SQL de nouveau. Les liens qu'elle détient à votre mappé objets sont faibles référencement, à condition que les objets soient propres des changements à venir, de sorte que même à cet égard, laSession
se vide de lui-même de retour pour une nouvelle marque de l'état lors de votre demande perd toutes les références à des objets mappés. Si vous le laisser à sa valeur par défaut"expire_on_commit"
réglage, puis tous les objets sont expirés après un commit. SiSession
se bloque autour de cinq ou vingt minutes, et toutes sortes de choses ont changé dans la base de données la prochaine fois que vous l'utilisez, il va charger le tout de la marque nouvel état la prochaine fois que vous accéder à ces objets, même si ils ont été assis dans la mémoire pour une vingtaine de minutes.Dans les applications web, nous avons l'habitude de dire, hey, pourquoi ne pas vous faire une nouvelle marque
Session
sur chaque demande, plutôt que d'utiliser le même maintes et maintes fois. Cette pratique assure que la nouvelle demande commence "propre". Si certains objets de la demande précédente, n'ont pas été nettoyée encore, et si vous avez peut-être désactivé"expire_on_commit"
, peut-être certains de l'état de la demande précédente est toujours traîner, et que l'état pourrait même être assez vieux. Si vous êtes prudent de laisserexpire_on_commit
allumé et certainement appelcommit()
ourollback()
à la demande de la fin, alors c'est bien beau, mais si vous commencez avec une nouvelle marqueSession
, alors il n'est même pas une question que vous êtes commencer le nettoyage. Donc, l'idée de départ de chaque demande avec un nouveauSession
est vraiment juste de la façon la plus simple de s'assurer que vous êtes de départ frais, et faire de l'utilisation deexpire_on_commit
assez bien option, que ce drapeau peut encourir beaucoup de SQL pour une opération qui appellecommit()
au moyen d'une série d'opérations. Ne sais pas si cela répond à votre question.De la prochaine ronde, ce que vous mentionnez sur le filetage. Si votre application est multithread, nous vous recommandons de faire assurer la
Session
dans l'utilisation de locaux à...quelque chose.scoped_session()
par défaut rend local pour le thread courant. Dans une application web, du local à la demande est en fait encore mieux. En flacon de SQLAlchemy envoie une coutume "fonction oscilloscope" àscoped_session()
de sorte que vous obtenez une demande d'étendue de session. La moyenne de la Pyramide de l'application des bâtons de la Séance, dans la "demande" du registre. Lors de l'utilisation de programmes comme ceux-ci, le "créer une nouvelle Session sur le début de la demande de" l'idée continue à ressembler à la façon la plus simple de garder les choses en ordre.En plus de l'excellente zzzeek réponse, voici une recette simple pour créer rapidement du jetable, de l'auto-joint sessions:
Utilisation:
Vous pouvez créer une session à l'aide de la db