使用psycopg2如何避免使用连接上下文管理器

时间:2019-03-15 19:26:35

标签: python postgresql psycopg2

使用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是绝对必要的,否则您将获得许多无法解释的锁。

我的问题是:有没有一种方法可以建立连接以避免使用它?

3 个答案:

答案 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))