SQL Alchemy 重复提交
我现在在我的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说得对。