You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL Python代码首次执行正常,二次执行报psycopg2连接已关闭错误

解决psycopg2第二次执行报错"connection already closed"的问题

问题原因

  • 你使用了全局的conn对象,并且用with conn:上下文管理器包裹代码。psycopg2的这个上下文管理器在代码块结束时会自动关闭连接,第一次执行完函数后conn就已经失效,第二次调用自然报错。
  • 代码还存在两个小问题:用format拼接SQL有注入风险,else语句缩进错误。

解决方案

1. 避免全局连接,每次函数调用时创建新连接

不要依赖全局连接对象,而是在函数内部创建数据库连接,确保每次执行都有活跃的连接可用。

2. 安全构建SQL查询

放弃format拼接SQL的方式,改用参数化查询,既避免SQL注入,又能灵活处理可选条件。

修改后的完整代码

import psycopg2

def clean_tables(account_id, node_id, scope_id, node_type):
    # 替换为你的数据库连接参数,也可从配置文件读取
    conn_params = {
        "dbname": "your_database",
        "user": "your_user",
        "password": "your_password",
        "host": "your_host"
    }
    
    # 上下文管理器包裹连接创建,自动管理连接生命周期
    with psycopg2.connect(**conn_params) as conn:
        with conn.cursor() as cur:
            print(account_id, "account_id__")
            check_id_query = "SELECT uuid FROM my_accounts WHERE name = %s"
            cur.execute(check_id_query, (account_id,))
            result = cur.fetchone()

            if result:
                uuid = result[0]
                print("ID:", uuid)
                # 基础删除语句
                clean_record_query = """
                    DELETE FROM my_collections 
                    WHERE collection_id = %s 
                    AND cmetadata->>'node_type' = %s 
                    AND cmetadata->>'node_id' = %s
                """
                query_params = [uuid, node_type, node_id]
                
                # 动态添加scope_id条件
                if scope_id:
                    clean_record_query += " AND cmetadata->>'scope_id' = %s"
                    query_params.append(scope_id)
                
                print(clean_record_query, "clean_record_query_")
                cur.execute(clean_record_query, tuple(query_params))

                if cur.rowcount > 0:
                    print("Record deleted successfully.")
                else:
                    print("No record found to delete.")
            else:
                print("No ID found for the given account_id.")

额外说明

  • 每次调用函数都会创建新连接,彻底避免连接被提前关闭的问题。
  • with psycopg2.connect(...)会在代码块结束时自动提交事务(无异常情况下),无需手动调用conn.commit()。
  • with conn.cursor()会自动关闭游标,无需手动清理资源。

内容的提问来源于stack exchange,提问作者Ninja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:55:01