【发布时间】:2017-01-05 17:48:04
【问题描述】:
首先我要声明,我很清楚 psycopg 会打开一个需要提交才能进行数据库更新的事务。
但是这里是关于提交的文档的引用:
提交()
向数据库提交任何待处理的事务。
默认情况下,Psycopg 在执行第一个命令之前打开一个事务:如果没有调用 commit(),任何数据操作的效果都会丢失。
连接也可以设置为“自动提交”模式:没有事务自动打开,命令立即生效。有关详细信息,请参阅事务控制。
在 2.5 版更改:如果在 with 语句中使用连接,如果在 with 块中没有引发异常,则自动调用该方法。
同样的回滚:
回滚()
回滚到任何待处理事务的开始。关闭连接而不首先提交更改将导致执行隐式回滚。
2.5 版更改:如果在 with 语句中使用连接,则在 with 块中引发异常时自动调用该方法。
但这似乎对我不起作用。也许我很挑剔,并且应该始终养成明确提交的习惯(但如果我忘记它会发生回滚,那就太好了)。我想知道是否有人提出了同样的问题,或者我的 with 语句使用不正确。
这是我的代码的样子:
import psycopg2
from contextlib import closing
with closing(psycopg2.connect(
#conn params
) as conn, \
closing(conn.cursor()) as cur:
try:
sql = #query
cur.execute(sql)
output = cur.statusmessage
print output
except Exception, e :
print "Error message : {}".format(e)
raise
这不起作用。查询本身没有问题,因为我得到: 更新 842518 作为预期的输出。但是,由于我的数据库没有更新,因此显然没有提交来自连接的更改。 如果我添加
conn.commit()
在 try 语句中它有效,但重点是避免这样做。
我的 psycopg2 版本是 2.6。
【问题讨论】:
-
只是一种预感,但是将连接和游标对象包装在
closing中会扰乱它们的上下文处理;他们自己就是上下文管理器。closing包装器只会在退出时调用它们的close()方法。 -
@IljaEverilä 尝试删除
closing,它确实有效。虽然现在我觉得我应该手动调用conn.close()和cur.close()。随时发表您的评论作为我会接受的答案
标签: python python-2.7 psycopg2