【问题标题】:When should I commit with SQLAlchemy using a for loop?我什么时候应该使用 for 循环提交 SQLAlchemy?
【发布时间】:2013-01-17 22:02:41
【问题描述】:

哪个是正确的?我知道第一个会起作用,但我怀疑它对数据库的工作可能比必要的要多。第二个工作是否同样有效,但对数据库的工作更少?我正在使用 MySQL FWIW。

for item in items:
    db.session.add(item)
    db.session.commit()

for item in items:
    db.session.add(item)
db.session.commit()

【问题讨论】:

  • 你一共执行了多少操作?它们是资源密集型的吗?除非有任何理由你不想在每个之后提交,否则我不明白你为什么不想总是使用 #1。

标签: python mysql sqlalchemy


【解决方案1】:

我认为您的第二个解决方案更好,但这取决于您如何配置会话。特别是自动刷新和自动提交设置。此外,您应该使用对事务有良好支持的引擎,例如 innodb。

假设您同时关闭了 autocommit 和 autoflush,那么您将把 insert 刷新到服务器,提交之前的事务,然后在每次迭代时创建另一个事务,这在 SQLAlchemy 和 MySQL 中都会产生大量不必要的工作。

如果您有一个要添加的简单项目列表(如示例中所示),我建议您使用 add_all,否则,如果您确实需要循环,那么一定要在循环外应用提交。

http://docs.sqlalchemy.org/en/latest/orm/session.html#sqlalchemy.orm.session.Session.add_all

db.session.add_all(items)
db.session.commit()

另外需要注意的是,如果在循环的中途出现问题,您的事务将回滚仅写入循环中的先前提交,如果您正在使用事务,这可能不是您想要的。例如,如果在循环中途发生错误,则列表中只有一半的项目可能会写入数据库。而在循环外调用 commit 可以保证你的循环已经完成并且将全部提交或全部回滚。

【讨论】:

  • +1 用于指出 add_all。有点令人沮丧的是 sql_alchemy 文档没有以某种入门页面将其放在首位和中心...
  • @adam-hughes 在Tutorial 中提到。我认为 sqlalchemy 的深度如此之深,很容易让人不知所措。
【解决方案2】:

添加解决方案:这是使用 add_all() 的方法

user1 = User(name='user1')
user2 = User(name='user2')
session.add(user1)
session.add(user2)

session.commit()     # write changes to the database

而不是两个添加行使用

session.add_all([user1, user2])

【讨论】:

    【解决方案3】:

    你可以用这个:

    session.bulk_save_objects([User, User, Permission])

    【讨论】:

      猜你喜欢
      • 2011-11-12
      • 2014-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-02
      • 2021-09-07
      • 1970-01-01
      • 2012-09-22
      相关资源
      最近更新 更多