Pandas 和 SQLAlchemy:使用来自 engine.begin() 的连接时,带有 SQLAlchemy 2.0 fututre=True 的 df.to_sql() 会引发错误
Posted
技术标签:
【中文标题】Pandas 和 SQLAlchemy:使用来自 engine.begin() 的连接时,带有 SQLAlchemy 2.0 fututre=True 的 df.to_sql() 会引发错误【英文标题】:Pandas and SQLAlchemy: df.to_sql() with SQLAlchemy 2.0 fututre=True throws an error when using a connection from engine.begin() 【发布时间】:2022-01-01 03:03:45 【问题描述】:我试图在 MS SQL Server 中从 pandas DataFrame 中插入一个表。
据我了解,这是一个两步过程:
在临时表中执行 pandas df.to_sql() 执行神奇的 sql 将临时表合并到现有的最终表中这可行,但前提是我在 create_engine 调用中设置了 future=False。
self.engine = create_engine(self.url, echo=True, future=False)
with self.engine.begin() as conn:
df.to_sql("#update_table", conn, if_exists="append", index=False)
# merge...
sql = f"""\
-- magic sql
"""
result = conn.execute(text(sql)).fetchone()
当使用 future=True 我得到这个错误:
Traceback (most recent call last):
File "/usr/local/Caskroom/miniconda/base/envs/dc_uk/lib/python3.9/site-packages/pandas/io/sql.py", line 1340, in insert_records
table.insert(chunksize=chunksize, method=method)
File "/usr/local/Caskroom/miniconda/base/envs/dc_uk/lib/python3.9/site-packages/pandas/io/sql.py", line 959, in insert
with self.pd_sql.run_transaction() as conn:
File "/usr/local/Caskroom/miniconda/base/envs/dc_uk/lib/python3.9/contextlib.py", line 119, in __enter__
return next(self.gen)
File "/usr/local/Caskroom/miniconda/base/envs/dc_uk/lib/python3.9/site-packages/pandas/io/sql.py", line 1416, in run_transaction
with self.connectable.begin() as tx:
File "/usr/local/Caskroom/miniconda/base/envs/dc_uk/lib/python3.9/site-packages/sqlalchemy/future/engine.py", line 144, in begin
return super(Connection, self).begin()
File "/usr/local/Caskroom/miniconda/base/envs/dc_uk/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 766, in begin
raise exc.InvalidRequestError(
sqlalchemy.exc.InvalidRequestError: This connection has already initialized a SQLAlchemy Transaction() object via begin() or autobegin; can't call begin() here unless rollback() or commit() is called first.
似乎 pandas 中的某些东西(还)无法处理 SA2 中的变化。 :(
今年早些时候有一些关于 SQLAlchemy 2.0 的问题,但都已解决。
我的问题: 我做错什么了吗?或者这仍然是一个悬而未决的问题...?
PS: 这是在 mac、python 3.9.7、pandas 1.3.4 和 SQLAlchemy 1.4.27 上。
【问题讨论】:
【参考方案1】:根据文档,“未来”会导致事务自动启动,因此您无需调用 .begin()
。
例如
with engine.connect() as conn:
conn.execute(...)
conn.execute(...)
conn.commit()
conn.execute(...)
conn.execute(...)
conn.commit()
method sqlalchemy.future.Connection.begin()
【讨论】:
给出一个新错误:File "/Users/ar/src/fuelminr/dc_uk_gold/src/DataFactory/scores.py", line 301, in scores_upsert with self.engine as conn: AttributeError: __enter__
... :/以上是关于Pandas 和 SQLAlchemy:使用来自 engine.begin() 的连接时,带有 SQLAlchemy 2.0 fututre=True 的 df.to_sql() 会引发错误的主要内容,如果未能解决你的问题,请参考以下文章
截断表不适用于 SQL Server sqlalchemy 引擎和 pandas
如何在 SQLAlchemy 的`create_engine` 中使用`charset` 和`encoding`(创建pandas 数据框)?
如何使用 pandas sqlalchemy 和 psycopg2 处理 NaT
想要使用 pandas 和 sqlalchemy 从查询是变量(不和谐用户名)的数据库中选择所有内容
无法在 ETL 过程中使用 Pandas 和 SQLAlchemy 将列名从 CSV 更改为 SQL Server DB