SQLAlchemy 在查询 [INFORMATION_SCHEMA].[TABLES] 时插入期间挂起

Joe*_*Joe 6 python sql-server sqlalchemy pyodbc pandas

我有一个使用 SQLAlchemy 将一些数据插入 MS SQL Server 数据库的 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')
Run Code Online (Sandbox Code Playgroud)

我此时数据库中正在发生其他“事情”,包括一些开放事务,我的猜测是,无论出于何种原因,查询都会以[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)
Run Code Online (Sandbox Code Playgroud)

请注意,当我在一天中没有进行其他数据库事务的其他时间运行 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',)
...
Run Code Online (Sandbox Code Playgroud)

更新2: 显然,当在开放事务中创建表或其他对象但尚未提交时,查询[INFORMATION_SCHEMA].[TABLES]将被阻止()。有熟悉 SQLAlchemy 内部结构的人建议如何阻止它首先进行此查询吗?

更新 3:在 SQLAlchemy github(问题链接)上发布此问题后,SQLAlchemy 开发人员确认 [INFORMATION_SCHEMA].[TABLES] 的查询实际上是由 Pandas函数 to_sql()引起的。

所以,我的新问题是有人知道如何在 Pandasto_sql()函数中禁用这种行为吗?我查看了文档,但找不到任何有帮助的内容。

Joe*_*Joe 1

从 pandas v.2.2.0 开始,您可以覆盖运行导致阻塞/死锁的检查的 pandas 方法。在调用之前添加以下内容to_sql

from pandas.io.sql import SQLDatabase
def pass_check_case_sensitive(*args, **kwargs):
    pass
SQLDatabase.check_case_sensitive = pass_check_case_sensitive
Run Code Online (Sandbox Code Playgroud)