使用psycopg2时,连接和查询数据库的工作原理如下
conn = psycopg2.connect('connection string')
with conn:
cur=conn.cursor()
cur.execute("SELECT * FROM pg_stat_activity") #simple query
rows = cur.fetchall()
for row in rows:
print (row)
经过反复试验,我发现with conn
是绝对必要的,否则您将获得许多无法解释的锁。
我的问题是:有没有一种方法可以建立连接以避免使用它?
答案 0 :(得分:5)
从https://www.psycopg.org/docs/usage.html,
警告
与文件对象或其他资源不同,退出连接的 with 阻止不关闭连接,而仅关闭交易 与之相关。如果要确保连接已关闭 在某一点之后,您仍然应该使用try-catch块:
conn = psycopg2.connect(DSN)
try:
# connection usage
finally:
conn.close()
答案 1 :(得分:1)
从2.5版开始,psycopg2应该像应该那样支持with
语句。
文件:https://www.psycopg.org/docs/usage.html#with-statement
答案 2 :(得分:0)
在 psycopg
中,上下文管理器的实现方式是 with 语句只会终止事务而不为您关闭连接。连接需要您单独关闭。
如果您的交易出现错误,您可以选择回滚并引发错误。
一种方法是自己编写连接关闭逻辑。
def with_connection(func):
"""
Function decorator for passing connections
"""
def connection(*args, **kwargs):
# Here, you may even use a connection pool
conn = psycopg.connect(DSN)
try:
rv = func(conn, *args, **kwargs)
except Exception as e:
conn.rollback()
raise e
else:
# Can decide to see if you need to commit the transaction or not
conn.commit()
finally:
conn.close()
return rv
return connection
@with_connection
def run_sql(conn, arg1):
cur = conn.cursor()
cur.execute(SQL, (arg1))