【发布时间】:2020-11-18 03:50:31
【问题描述】:
我遇到了一个非常令人沮丧的错误,但我不确定该如何表达我的问题。核心行为似乎如下:
1) Create a new db.session, bound to an existing PostgreSQL database
2) Run db.session.add(myObj)
3) Run db.session.commit()
>>> Check the database using PGAdmin, myObj was successfully uploaded
4) *
5) Run db.session.query(myClass) as many times as I want
>>> Returns [myObj]
6) Run db.session.query(myClass).filter(anyFilterThatDoesNotActuallyChangeResult)
>>> Returns [myObj]
>>> BUG >>> 5 seconds later, another copy of myObj is added to the database (visible in PGAdmin)
7) Repeat step 6 as many times as you want
>>> Returns [myObj, myObj]
8) Repeat step 5
>>> Returns [myObj, myObj]
>>> BUG >>> 5 seconds later, another copy of myObj is added to the database (visible in PGAdmin)
更多令人困惑的信息:我可以在第 4 步完全关闭并重新启动我的文本编辑器和 python 环境,但错误行为仍然存在。
我的直觉是,COMMIT 字符串以某种方式被缓存在某处(在 SQLAlchemy 或 PostgreSQL 中),每当查询命令发生更改时,都会触发数据库上的某种自动刷新,从而重新运行提交字符串,但实际上并未清除成功后的缓存。
----------------- 编辑 -----------------
忽略此问题的其余部分,因为它与手头的错误无关。
为了进一步探索这种行为,我运行了以下代码:
1) Create a new db.session, bound to an existing PostgreSQL database
2) Run db.session.add(myObj)
3) Run db.session.commit()
4) Run db.session.commit()
其中,我希望只添加一个 myObj 副本,但实际上它添加了两个!!!!这打破了我对提交正在做什么的理解——特别是自动刷新、结束事务以及从其“待办事项”列表中删除 add(myObj)。此外,我尝试在第 3 行和第 4 行之间运行的代码都不会阻止这种行为:例如 db.session.expire_all()
我是数据库方面的完全菜鸟(这是我的第一个项目),因此我将不胜感激任何建议,尤其是关于如何克服此错误的明确分步建议。例如。我应该添加什么代码,在哪里清除这样的缓存?
【问题讨论】:
-
看起来你很接近拥有minimal reproducible example - 你能包括一个表定义和重现双插入双提交行为所需的代码吗?
-
是的,请edit 您的问题包括minimal reproducible example 并指定您正在使用的 SQLAlchemy 和 DBAPI 层(例如 psycopg2)的版本。
标签: python database caching visual-studio-code sqlalchemy