Python SQLAlchemy不更新模型,将忽略所有已更改的字段,但上次修改的字段除外

Python SQLAlchemy不更新模型,将忽略所有已更改的字段,但上次修改的字段除外,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,我有以下型号: 类模型(db.Base): “”“用于存储项目运行状况快照的表。”“” __tablename\uuuu='my\u table' id=列(整数(),主键=True) 第一个属性=列(整数) 第二个属性=列(整数) 创建时间=列(日期时间) 我需要更新现有对象的属性。事情就是这样发生的: ipdb>模型=( db.session.query(模型) .过滤器(id=5908) .first() ) ipdb>logging.getLogger('sqlalchemy.engi

我有以下型号:

类模型(db.Base):
“”“用于存储项目运行状况快照的表。”“”
__tablename\uuuu='my\u table'
id=列(整数(),主键=True)
第一个属性=列(整数)
第二个属性=列(整数)
创建时间=列(日期时间)
我需要更新现有对象的属性。事情就是这样发生的:

ipdb>模型=(
db.session.query(模型)
.过滤器(id=5908)
.first()
)
ipdb>logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
ipdb>model.first_属性
1.
ipdb>model.second_属性
1.
ipdb>model.first_属性=object.some_值
ipdb>model.second_属性=object.other_值
ipdb>model.created_at=get_utc_now()
ipdb>model.first_属性
0
ipdb>model.second_属性
0
ipdb>db.session.add(模型)
ipdb>db.session.commit()
ipdb>model.first_属性
1.
ipdb>model.second_属性
1.
因此,模型最初的值1已更改为0,提交后仍为1。数据库中的值也是如此

实际上,debug语句承认它不关心
第一个属性
第二个属性
,它只更新在处创建的

2020-02-13 10:55:29,133 - sqlalchemy.engine.base.Engine - INFO - BEGIN (implicit)
2020-02-13 10:55:29,137 - sqlalchemy.engine.base.Engine - INFO - UPDATE my_table SET created_at=%(created_at)s WHERE my_table.id = %(id)s
2020-02-13 10:55:29,138 - sqlalchemy.engine.base.Engine - INFO - {'created_at': datetime.datetime(2020, 2, 13, 9, 54, 9, 610208, tzinfo=tzutc()), 'id': 5908}
2020-02-13 10:55:29,345 - sqlalchemy.engine.base.Engine - INFO - COMMIT

有趣的是,唯一更新的字段是在将模型添加到会话之前最后修改的字段。我已经交换了
模型。在
模型中创建了\u。第一个\u属性
值分配,将第二个属性保留为
db.session.add(model)
之前的最后一个属性,它确实得到了更新(这是唯一一个更新的)。

我可以使用
db.session.merge(model)
而不是
db.session.add>来完成这项工作(型号)

看起来,由于某种原因,我仍然没有真正了解到,
模型
实例不在会话范围内。
合并
根据主键属性将给定实例的状态复制到它在会话中的状态(您仍然需要提交事务以保存数据库中的更改)


SQLAlchemy文档说明:

请提供一个,或者换句话说,您的模型定义,以及生成
模型
实例的代码。不确定您是否启用了该设置,但所有模型在提交时都应无效,提交后需要从数据库重新加载它们?@Mikkoohtama在正常操作中,SQLA不会在自动运行。这里还有其他问题。从提示中看,命令似乎正在调试器中运行。这可能与奇怪的行为有关,也可能与此无关。@IljaEverilä,它也在生产中发生。我还尝试从调试器手动检查它。错过了对
add()的调用
阅读之前的问题。如果模型对象是查询的结果,那么它应该是多余的,在这种情况下,对象应该已经是生成它的会话的一部分。
db.session
在Flask SQLAlchemy中是一个作用域会话,因此它服务于线程本地会话。这可能是需要研究的问题。