SQLAlchemy开启future=True时用engine.begin()连接调用df.to_sql()报错
问题根源
你遇到的报错是pandas旧版本对SQLAlchemy 2.0兼容模式(future=True)适配不完善导致的,操作逻辑本身没有错误。
SQLAlchemy开启future=True后,连接创建时会自动初始化事务,不允许重复调用begin()开启新事务。你代码中已经通过with self.engine.begin()开启了外层全局事务,但你使用的pandas 1.3.4版本中,df.to_sql()的内部逻辑会对传入的SQLAlchemy连接对象再次调用begin()开启嵌套事务,二者冲突就触发了这个报错。而future=False时SQLAlchemy 1.4.x沿用旧版事务逻辑,没有重复开启事务的校验,所以可以正常运行。
解决方案
方案1:升级pandas版本(推荐)
该兼容问题在pandas 1.4.0及之后的版本已经正式修复,你只需要将pandas升级到1.4.0以上版本,原有代码不需要做任何修改,开启future=True即可正常运行。
pip install pandas>=1.4.0
方案2:临时兼容方案(无法升级pandas时使用)
如果当前环境不允许升级pandas,可以将底层DBAPI连接直接传给to_sql,绕开pandas对SQLAlchemy连接的事务处理逻辑,修改后的代码如下:
self.engine = create_engine(self.url, echo=True, future=True) with self.engine.begin() as conn: # 传入底层原生连接,避免pandas重复开启事务 df.to_sql("#update_table", conn.connection, if_exists="append", index=False) # 合并操作 sql = f"""\ -- 业务SQL逻辑 """ result = conn.execute(text(sql)).fetchone()
内容的提问来源于stack exchange,提问作者A. Rabus
相关产品推荐
相关产品推荐

