【问题标题】:Are there any side effects from calling SQLAlchemy flush() within code?在代码中调用 SQLAlchemy flush() 是否有任何副作用?
【发布时间】:2015-06-03 00:12:25
【问题描述】:

一点背景:

我正在使用pyramid 框架和SQLAlchemy。我的数据库会话由 pyramid_tm 和 ZTE 处理

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))

我有一个非常复杂的数据库设计,其中包含大量模型类、外键以及模型之间的复杂关系。

因此,在我的模型上执行一些非常复杂的逻辑以及从不同模型中的关系中删除、更新、插入和移动对象时,我曾经随机获得IntegrityError,这将在重新启动pserve 后消失。

这很奇怪,因为autoflush 已打开,理论上会话必须在我更改模型上的任何内容后立即刷新。

所以我对随机IntegrityError 的解决方案是在事情变得非常复杂时手动刷新我的逻辑中的会话。

自从我在我的逻辑中执行了DBSession.flush() 之后,我再也没有收到 IntegrityError。

问题

现在我有两个问题:

  1. 为什么 autoflush 不能防止完整性错误?是不是 autoflush 不清理模型,而DBSession.flush() 清理模型?

  2. 在我的代码中调用DBSession.flush() 是否有任何副作用?我真的想不出任何副作用(除了调用 DB 的性能开销很小)。我不太喜欢在我的代码中调用DBSession.flush(),因为它确实必须由框架处理。

另见

When should I be calling flush() on SQLAlchemy?

谢谢。

【问题讨论】:

  • 你能分享IntegrityError那是throw的完整消息吗?
  • 这里还有一点需要注意的是flush会将数据写入数据库,但是除非你使用commit,否则更改不会存储到数据库中,它们将被丢弃会话到期。如果您调用commit,则会刷新更改并使其持久化。
  • 谢谢阿达什。我的问题是在代码中手动调用flush而不是让框架处理它是否有任何副作用。
  • 这样没有副作用。但在我看来,只有在禁用自动刷新以防止混淆时,您才应该这样做。实际上,我建议不要使用 autoflush 并手动进行刷新和提交,因为这样可以更好地控制处理错误、如何回滚以及根据查询的方式优化对数据库的写入。

标签: python sqlalchemy pyramid flush


【解决方案1】:

很难说为什么你过去没有看到任何代码就得到IntegrityError,但理论上有一些场景autocommit实际上可能导致它通过刷新会议过早。例如:

COURSE_ID = 10
student = Student(name="Bob")
student.course_id = COURSE_ID

course = Course(id=COURSE_ID, name="SQLAlchemy")

如果您让 SQLAlchemy 刷新更改,上述代码可能会(尚未测试)在 autocommit 开启的情况下失败。

如果有帮助的话,我认为定期刷新会话没有任何害处,但同样,在没有任何代码示例的情况下,很难判断是否可以采取一些措施来避免手动刷新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-10
    • 1970-01-01
    相关资源
    最近更新 更多