【问题标题】:SQLAlchemy Repeated Commit()SQLAlchemy 重复提交()
【发布时间】: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()

我是数据库方面的完全菜鸟(这是我的第一个项目),因此我将不胜感激任何建议,尤其是关于如何克服此错误的明确分步建议。例如。我应该添加什么代码,在哪里清除这样的缓存?

【问题讨论】:

标签: python database caching visual-studio-code sqlalchemy


【解决方案1】:

事实证明,这个问题比我想象的还要糟糕。重复的步骤实际上比这更基本:

1) Save any file in the same directory as my session manager
>>> BUG >>> 15 seconds later another copy of myObj is added to the database

我正在使用 VS Code(版本:1.47.3),并且该错误仅在启用 Python 扩展时发生。

我的假设是,因为目录中的一个文件自动初始化了一个数据库会话(通过 pyscopg2),所以有一些缓存机制在管理不善的状态下执行该代码,它以某种方式成功地建立了一个新的引擎连接,然后是最后一个提交语句。

我已停止尝试对其进行调试,并转而对会话管理结构进行重构,以便仅在函数调用中建立连接,而不是在文件运行时建立。

感谢阅读。希望这可以帮助其他人解决这个令人发指的不可重现的错误。从字面上看,我觉得我快疯了:每次我心不在焉地保存我的文件时,就会出现一个神秘物体。我会在不同的点和不同的频率保存,所以行为看起来完全随机。我找到重现原始步骤的唯一原因是因为我使用的调试器在运行之前保存了文件。

-----------------最终解决方案-----------------

事实证明,我所有问题的根源在于我选择的名字。 我写了一些代码来测试我的 sql 代码,但愚蠢地将它命名为 test_XXX.py 然后,无论何时保存任何文件,pytest 都会自动扫描所有启动 test_* 的文件并运行它们,从而使我的整个 SQL 示例工作在后台运行。

请在下周收看更多关于“我本可以预防的事情”的冒险。

【讨论】:

    猜你喜欢
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    • 2015-11-02
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多