使用SQLAlchemy将DataFrame写入PostgreSQL时卡顿问题排查
问题排查与修复方案
核心问题:混用两种数据库连接引发锁阻塞
你同时使用psycopg2原生连接和SQLAlchemy连接操作同一张表,两个连接属于独立事务,必然引发锁竞争:
psycopg2执行TRUNCATE后,事务未立即提交,表锁会持续持有到最后pg_conn.commit(),此时df.to_sql用SQLAlchemy连接写入同一张表会被锁阻塞,导致程序卡住。- 若SQLAlchemy的写入操作先持有表锁,
psycopg2的TRUNCATE也会因等待锁释放而卡住。
修复步骤
1. 统一使用SQLAlchemy连接,删除冗余的psycopg2代码
SQLAlchemy可直接执行DDL语句,无需混用原生连接,从根源避免锁冲突:
from sqlalchemy import create_engine import requests import pandas as pd # 初始化SQLAlchemy引擎 engine = create_engine(conn_string) # 执行TRUNCATE并立即提交释放锁 with engine.connect() as conn: conn.execute('TRUNCATE TABLE schema1.table_1') conn.commit() # 拉取API数据 response = requests.get(url, auth=(uname, pwd)) response_data = response.json() df = pd.DataFrame.from_dict(response_data) # 写入数据库 df.to_sql('table_1', con=engine, if_exists='append', index=False, schema='schema1')
2. 避免TRUNCATE无限等待锁(可选)
如果目标表存在其他活跃事务,TRUNCATE会一直等待锁释放,可添加NOWAIT参数直接抛出错误,方便排查事务占用问题:
TRUNCATE TABLE schema1.table_1 NOWAIT;
3. 完善异常与资源管理(可选)
添加异常捕获,防止程序意外挂起或资源泄漏:
from sqlalchemy import create_engine import requests import pandas as pd engine = create_engine(conn_string) try: with engine.connect() as conn: conn.execute('TRUNCATE TABLE schema1.table_1') conn.commit() response = requests.get(url, auth=(uname, pwd)) response.raise_for_status() # 检查API请求是否成功 response_data = response.json() df = pd.DataFrame.from_dict(response_data) df.to_sql('table_1', con=engine, if_exists='append', index=False, schema='schema1') except Exception as e: print(f"执行出错: {str(e)}") finally: engine.dispose() # 释放引擎资源
内容的提问来源于stack exchange,提问作者Sab_91
相关产品推荐
相关产品推荐

