我有一个使用SQLAlchemy将数据插入到MS SQL Server DB的Python进程。当Python进程运行时,它会在插入期间挂起。我打开了SQLAlchemy日志以获得更多信息。我发现它挂起的原因是SQLAlchemy似乎正在请求整个数据库的表架构信息:
2020-10-30 08:12:07 [11444:6368] sqlalchemy.engine.base.Engine._execute_context(base.py:1235) INFO: SELECT [INFORMATION_SCHEMA].[TABLES].[TABLE_NAME]
FROM [INFORMATION_SCHEMA].[TABLES]
WHERE [INFORMATION_SCHEMA].[TABLES].[TABLE_SCHEMA] = CAST(? AS NVARCHAR(max)) AND [INFORMATION_SCHEMA].[TABLES].[TABLE_TYPE] = CAST(? AS NVARCHAR(max)) ORDER BY [INFORMATION_SCHEMA].[TABLES].[TABLE_NAME]
2020-10-30 08:12:07 [11444:6368] sqlalchemy.engine.base.Engine._execute_context(base.py:1240) INFO: ('dbo', 'BASE TABLE')
我数据库中有其他“东西”正在进行,包括一些未完成的事务,我的猜测是由于某种原因查询 [INFORMATION_SCHEMA].[TABLES]
会创建一些死锁或阻塞。
我也读到过 (这里),[INFORMATION_SCHEMA].[TABLES]
是一个视图,不会引起死锁,这与我猜测导致此问题的情况相矛盾。
我的问题是:我能否更改 SQLAlchemy 的配置/设置,以便它首先不进行此查询?
更新1:插入的 Python 代码如下:
with sqlalchemy.create_engine("mssql+pyodbc:///?odbc_connect=%s" % params).connect() as connection:
# df is a Pandas DataFrame
df.to_sql(name=my_table, con=connection, if_exists='append', index=False)
请注意,当我在其他没有进行数据库事务的时间运行Python脚本时,代码可以正常工作。在这些情况下,日志会立即继续列出数据库中的所有表格:
2020-10-30 08:13:03 [11444:6368] sqlalchemy.engine.base.Engine._execute_context(base.py:1235) INFO: SELECT [INFORMATION_SCHEMA].[TABLES].[TABLE_NAME]
FROM [INFORMATION_SCHEMA].[TABLES]
WHERE [INFORMATION_SCHEMA].[TABLES].[TABLE_SCHEMA] = CAST(? AS NVARCHAR(max)) AND [INFORMATION_SCHEMA].[TABLES].[TABLE_TYPE] = CAST(? AS NVARCHAR(max)) ORDER BY [INFORMATION_SCHEMA].[TABLES].[TABLE_NAME]
2020-10-30 08:13:03 [11444:6368] sqlalchemy.engine.base.Engine._execute_context(base.py:1240) INFO: ('dbo', 'BASE TABLE')
2020-10-30 08:13:03 [11444:6368] sqlalchemy.engine.base.Engine._init_metadata(result.py:810) DEBUG: Col ('TABLE_NAME',)
2020-10-30 08:13:03 [11444:6368] sqlalchemy.engine.base.Engine.process_rows(result.py:1260) DEBUG: Row ('t_table1',)
2020-10-30 08:13:03 [11444:6368] sqlalchemy.engine.base.Engine.process_rows(result.py:1260) DEBUG: Row ('t_table2',)
...
更新2:
显然,当在一个未提交的事务中创建一个表或其他对象时,查询[INFORMATION_SCHEMA].[TABLES]
将被阻塞(来源)。有没有人熟悉SQLAlchemy的内部结构,以建议如何防止它首先进行此查询?
更新3:在将此问题发布到SQLAlchemy github后(问题链接),SQLAlchemy开发人员确认[INFORMATION_SCHEMA].[TABLES]的查询实际上是由Pandas函数 to_sql()
引起的。
因此,我的新问题是,有没有人知道如何在Pandas的to_sql()
函数中禁用此行为?我查看了文档,但找不到任何有助于解决这个问题的东西。