SQLAlchemy:flush()和commit()有什么区别?
SQLAlchemy中的flush()
和commit()
之间有什么区别?
我已经阅读了文档,但是没有比这更明智的了 – 他们似乎假定我没有预先的理解。
我特别感兴趣的是他们对内存使用的影响。 我从一系列文件(总共大约500万行)将一些数据加载到数据库中,而且会话偶尔会翻倒 – 这是一个大型数据库和一个内存不多的机器。
我想知道如果我使用了太多的commit()
和没有足够的flush()
调用 – 但是没有真正理解它们之间的区别,很难说清楚!
Session对象基本上是数据库更新(更新,插入,删除)的持续事务。 这些操作在提交之前不会持久保存到数据库中(如果程序在中间事务处理中由于某种原因而中止,任何未提交的更改都将丢失)。
会话对象使用session.add()
注册事务操作,但在session.flush()
被调用之前还没有将它们传递给数据库。
session.flush()
向数据库传递一系列操作(插入,更新,删除)。 数据库将其维护为事务中的挂起操作。 这些更改不会永久保存到磁盘,或者直到数据库接收到当前事务的COMMIT(这是session.commit()
执行的操作)才可见。
session.commit()
将这些更改提交(保留)到数据库。
flush()
总是作为commit()
( 1 )调用的一部分被调用。
当您使用Session对象来查询数据库时,查询将返回数据库的结果以及它所保存的未提交事务的刷新部分的结果。 默认情况下,会话对象自动autoflush
其操作,但可以禁用。
希望这个例子会使这个更清晰:
#--- s = Session() s.add(Foo('A')) # The Foo('A') object has been added to the session. # It has not been committed to the database yet, # but is returned as part of a query. print 1, s.query(Foo).all() s.commit() #--- s2 = Session() s2.autoflush = False s2.add(Foo('B')) print 2, s2.query(Foo).all() # The Foo('B') object is *not* returned # as part of this query because it hasn't # been flushed yet. s2.flush() # Now, Foo('B') is in the same state as # Foo('A') was above. print 3, s2.query(Foo).all() s2.rollback() # Foo('B') has not been committed, and rolling # back the session's transaction removes it # from the session. print 4, s2.query(Foo).all() #--- Output: 1 [<Foo('A')>] 2 [<Foo('A')>] 3 [<Foo('A')>, <Foo('B')>] 4 [<Foo('A')>]
正如@snapshoe所说
flush()
将你的SQL语句发送到数据库
commit()
提交事务。
当session.autocommit == False:
如果你的autoflush == True,commit()会调用flush()。
当session.autocommit == True时:
如果你还没有开始一个事务(你可能没有,因为你可能只使用这个模式来避免手动pipe理事务),你不能调用commit()。
在这种模式下,你必须调用flush()来保存你的ORM改变。 有效的刷新也提交您的数据。