SQL Alchemy 重复提交

1 投票
2 回答
1446 浏览
提问于 2025-04-16 19:59

我现在在我的Cherrypy应用程序中遇到了一个问题。
在我自己写的会话模块里,当我执行session.add()时,竟然同一个对象被更新了两次。

cherrypy.request.SessionManager.user_data = user

try:

    db_session.add(cherrypy.request.SessionManager)
    db_session.commit()

将返回

2011-06-21 09:16:48,991 INFO sqlalchemy.engine.base.Engine.0x...04cL BEGIN (implicit)
2011-06-21 09:16:49,015 INFO sqlalchemy.engine.base.Engine.0x...04cL SELECT ..... 
FROM "Clients_Users" 
WHERE "Clients_Users".username = %(username_1)s AND "Clients_Users".password = %(password_1)s 
LIMIT 1 OFFSET 0
2011-06-21 09:16:49,015 INFO sqlalchemy.engine.base.Engine.0x...04cL {'password_1': '123', 'username_1': u'1'}
2011-06-21 09:16:49,047 INFO sqlalchemy.engine.base.Engine.0x...04cL UPDATE "SYS_Sessions" SET user_data=%(user_data)s WHERE "SYS_Sessions".id = %(SYS_Sessions_id)s
2011-06-21 09:16:49,067 INFO sqlalchemy.engine.base.Engine.0x...04cL {'SYS_Sessions_id': 92L, 'user_data': <psycopg2._psycopg.Binary object at 0x8a7c06c>}
2011-06-21 09:16:49,071 INFO sqlalchemy.engine.base.Engine.0x...04cL COMMIT
2011-06-21 09:16:49,093 INFO sqlalchemy.engine.base.Engine.0x...04cL BEGIN (implicit)
2011-06-21 09:16:49,095 INFO sqlalchemy.engine.base.Engine.0x...04cL UPDATE "SYS_Sessions" SET user_data=%(user_data)s WHERE "SYS_Sessions".id = %(SYS_Sessions_id)s
2011-06-21 09:16:49,095 INFO sqlalchemy.engine.base.Engine.0x...04cL {'SYS_Sessions_id': 92L, 'user_data': <psycopg2._psycopg.Binary object at 0x8a8424c>}
2011-06-21 09:16:49,108 INFO sqlalchemy.engine.base.Engine.0x...04cL COMMIT

有没有人遇到过这种情况?
附注:在我做的其他模块中并没有发生这种情况。

2 个回答

1

你可以试着把用户数据放到会话里,而不是把SessionManager对象直接放进去。这样做至少能让调试变得简单一些。

现在我不太确定你在cherrypy的SessionManager里是否有数据库会话——这看起来不太好,但也许sqlalchemy可以处理这个问题?或者你可能在对这个对象进行多个修改,而这些修改不能同时在数据库里完成——比如说,这可能就是开启回显后某些级联操作的样子。你使用的级联值是什么?

从sql的内容来看,我不太明白第二次更新的是什么。看起来只是一些隐含的东西。你可能需要展示一些相关对象的代码,或者一些导致更新的代码,这样才能得到更好的答案。不过也许上面的直觉会对你有帮助。祝你好运!

1

好的,抱歉让大家等了这么久,因为我在度假。

不过,为了防止重复提交,你需要把对象从会话中移除,这可以通过使用 session.expunge() 来实现。

还有一件事。

使用 session.merge() 可以让你重新使用已经被移除的对象。

希望这对有需要的人有所帮助。

附言:要记得,某个对象可能会出现问题,或者未来对Alchemy的更新可能会导致不兼容。所以,profane说得对。

撰写回答