【问题标题】:SQLAlchemy: Inconsistent behaviour after commitSQLAlchemy:提交后行为不一致
【发布时间】:2017-02-03 19:25:32
【问题描述】:

我有一个 SQLAlchemy ORM,它的 __str__() 函数打印一个键和值表。 以下代码将其提交到数据库并打印出来(为了清楚起见,属性名称已更改):

user.some_attribute = <Some integer>
session.add(user)
session.commit()
app.logger.debug("some_attribute is %s" % user.some_attribute)
app.logger.debug("Created a DB row:\n%s" % user)

这里的疯狂之处在于,第二个调试打印只有在第一个调试存在时才有效!

换句话说,如果两条调试线存在,我得到:

some_attribute is 5
+------------------------------------------+-------------------------------------------------+
| Field                                    | Value                                           |
+------------------------------------------+-------------------------------------------------+
| creation_time                            | 2016-09-26 15:25:45.630230                      |
| description                              | Test Poly 835                                   |
| destination_truck_ids                    | ['A']                                             |
| future_event_series_id                   | None                                            |
| id                                       | 1017                                            |
...

但如果只有第二个存在,我会得到:

+-------+-------+
| Field | Value |
+-------+-------+
+-------+-------+

为什么 ORM 没有属性,除非它的特性之一被打印出来?

【问题讨论】:

  • 你是如何让__str__ 生成所有这些的?就我而言,str(user) 是我一直期望的:&lt;__main__.User object at 0x0000000003866FD0&gt;

标签: python session orm sqlalchemy


【解决方案1】:

我找到了一种解决方法,尽管我不太确定问题的性质。

引用the manual:

默认情况下,Session 也会过期所有数据库加载状态 事务提交后的 ORM 管理属性。这使得 后续操作从数据库加载最新数据。 可以使用 expire_on_commit=False 选项禁用此行为 到 sessionmaker 或 Session 构造函数。

如果我用expire_on_commit=False 加载会话,问题就解决了——即使在提交之后我也得到了ORM。

【讨论】:

  • 这不是解决方法;这是国际海事组织的正确解决方案。如果您在提交后需要访问实例的属性而不再次加载它,请关闭expire_on_commit。我相信这个功能默认是开启的,因为它可以让简单的代码工作。如果您知道自己在做什么,您只需将其关闭即可。
  • 这很好,除了打印一个 ORM 属性会导致它重新出现。
猜你喜欢
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多