597 votes

SQLAlchemy : Quelle est la différence entre flush() et commit() ?

Quelle est la différence entre flush() y commit() dans SQLAlchemy ?

J'ai lu les documents, mais je n'en sais rien - ils semblent supposer une compréhension préalable que je n'ai pas.

Je suis particulièrement intéressé par leur impact sur l'utilisation de la mémoire. Je suis en train de charger des données dans une base de données à partir d'une série de fichiers (environ 5 millions de lignes au total) et ma session tombe parfois en panne - c'est une grande base de données et une machine avec peu de mémoire.

Je me demande si je n'en utilise pas trop. commit() et pas assez flush() mais sans vraiment comprendre quelle est la différence, c'est difficile à dire !

8voto

Ben Gorman Points 1075

Les réponses existantes n'ont pas beaucoup de sens, sauf si vous comprenez ce qu'est une base de données. transaction est. (C'était le cas pour moi jusqu'à récemment).

Parfois, vous pouvez vouloir exécuter plusieurs instructions SQL et les faire réussir ou échouer. dans son ensemble . Par exemple, si vous souhaitez effectuer un virement bancaire du compte A au compte B, vous devrez effectuer deux requêtes comme suit

UPDATE accounts SET value = value - 100 WHERE acct = 'A'
UPDATE accounts SET value = value + 100 WHERE acct = 'B'

Si la première requête réussit mais que la seconde échoue, c'est mauvais (pour des raisons évidentes). Nous devons donc trouver un moyen de traiter ces deux requêtes "comme un tout". La solution consiste à commencer par une instruction BEGIN et à terminer par une instruction COMMIT ou ROLLBACK, comme suit

BEGIN
UPDATE accounts SET value = value - 100 WHERE acct = 'A'
UPDATE accounts SET value = value + 100 WHERE acct = 'B'
COMMIT

Il s'agit d'une transaction unique .

Dans l'ORM de SQLAlchemy, cela pourrait ressembler à ceci

                                      # BEGIN issued here
acctA = session.query(Account).get(1) # SELECT issued here
acctB = session.query(Account).get(2) # SELECT issued here

acctA.value -= 100
acctB.value += 100

session.commit()                      # UPDATEs and COMMIT issued here 

Si vous surveillez quand les différentes requêtes sont exécutées, vous verrez que les UPDATE n'atteignent pas la base de données jusqu'à ce que vous appeliez session.commit() .

Dans certaines situations, il est préférable d'exécuter les instructions UPDATE avant d'émettre un COMMIT. (Peut-être que la base de données fournit un identifiant auto-incrémenté à l'objet et que vous voulez le récupérer avant de faire un COMMIT). Dans ces cas, vous pouvez explicitement flush() la session.

                                      # BEGIN issued here
acctA = session.query(Account).get(1) # SELECT issued here
acctB = session.query(Account).get(2) # SELECT issued here

acctA.value -= 100
acctB.value += 100

session.flush()                       # UPDATEs issued here 
session.commit()                      # COMMIT issued here

0voto

Commit () enregistre ces modifications dans la base de données. flush () est toujours appelé dans le cadre de l'appel commit () (1). Lorsque vous utilisez un objet Session pour interroger une base de données, la requête renvoie des résultats provenant à la fois de la base de données et des parties rouges de la transaction non enregistrée qu'elle exécute.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X