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
相关产品推荐
相关产品推荐

