SQLAlchemy 2.x操作MSSQL动态删建表时出现报错及语句不生效问题求助
SQLAlchemy 2.x操作MSSQL动态删建表时出现报错及语句不生效问题求助
我现在在使用SQLAlchemy 2.0.39 + Python 3.10.11做动态数据表的操作,已经成功通过下面的代码动态生成了映射类:
dynamic_class = type(table_name, (Base,), attributes)
现在我需要删除已存在的对应表,再用当前的类定义重建,但这一步出了问题。我写的删表和建表代码如下:
log.info(f"Dropping Table: mygrc.{table_name}") dynamic_class.__table__.drop(dbEngine, checkfirst=True) log.info(f"Creating Table: mygrc.{table_name}") Base.metadata.create_all(dbEngine, tables=[dynamic_class.__table__])
但无论是删表还是建表操作,都抛出了同样的错误:
No results. Previous SQL was not a query.
后来我尝试直接把编译后的SQL语句传给execute执行,虽然不再报错,但语句根本没生效(即使手动commit了),代码是这样的:
with dbEngine.connect() as connection: create_table_statement = str(dynamic_class.__table__.compile(dbEngine)) connection.execute(text(create_table_statement))
这里编译出来的create_table_statement是完全合法的建表语句,手动执行是有效的。
我还拿到了完整的报错栈:
Traceback (most recent call last): File "c:\Users\username\Documents\Coding\azure-pipeline\.venv\lib\site-packages\sqlalchemy\engine\base.py", line 1980, in _exec_single_context result = context._setup_result_proxy() File "c:\Users\username\Documents\Coding\azure-pipeline\.venv\lib\site-packages\sqlalchemy\engine\default.py", line 1838, in _setup_result_proxy strategy = _cursor.BufferedRowCursorFetchStrategy( File "c:\Users\username\Documents\Coding\azure-pipeline\.venv\lib\site-packages\sqlalchemy\engine\cursor.py", line 1188, in __init__ self._rowbuffer = collections.deque(dbapi_cursor.fetchmany(1)) pyodbc.ProgrammingError: No results. Previous SQL was not a query. The above exception was the direct cause of the following exception: Traceback (most recent call last): File "C:\Users\username\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main return _run_code(code, main_globals, None, File "C:\Users\username\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code exec(code, run_globals) File "c:\Users\username\.vscode\extensions\ms-python.debugpy-2025.4.1-win32-x64\bundled\libs\debugpy\__main__.py", line 71, in <module> cli.main() File "c:\Users\username\.vscode\extensions\ms-python.debugpy-2025.4.1-win32-x64\bundled\libs\debugpy/..\debugpy\server\cli.py", line 501, in main run() File "c:\Users\username\.vscode\extensions\ms-python.debugpy-2025.4.1-win32-x64\bundled\libs\debugpy/..\debugpy\server\cli.py", line 351, in run_file runpy.run_path(target, run_name="__main__") File "c:\Users\username\.vscode\extensions\ms-python.debugpy-2025.4.1-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 310, in run_path return _run_module_code(code, init_globals, run_name, pkg_name=pkg_name, script_name=fname) File "c:\Users\username\.vscode\extensions\ms-python.debugpy-2025.4.1-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 127, in _run_module_code _run_code(code, mod_globals, init_globals, mod_name, mod_spec, pkg_name, script_name) File "c:\Users\username\.vscode\extensions\ms-python.debugpy-2025.4.1-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 118, in _run_code exec(code, run_globals) File "C:\Users\username\Documents\Coding\azure-pipeline\mygrcreport.py", line 94, in <module> mygrc_3ps_inherent_risk, primary_key = mygrcreport_db.dynamic_table(schema, "mygrc_3ps_inherent_risk", dbEngine) File "\mygrcreport_db.py", line 81, in dynamic_table dynamic_class.__table__.drop(dbEngine, checkfirst=True) File "\.venv\lib\site-packages\sqlalchemy\sql\schema.py", line 1301, in drop bind._run_ddl_visitor(ddl.SchemaDropper, self, checkfirst=checkfirst) File "\.venv\lib\site-packages\sqlalchemy\engine\base.py", line 3249, in _run_ddl_visitor conn._run_ddl_visitor(visitorcallable, element, **kwargs) File "\.venv\lib\site-packages\sqlalchemy\engine\base.py", line 2456, in _run_ddl_visitor visitorcallable(self.dialect, self, **kwargs).traverse_single(element) File "\.venv\lib\site-packages\sqlalchemy\sql\visitors.py", line 664, in traverse_single return meth(obj, **kw) File "\.venv\lib\site-packages\sqlalchemy\sql\ddl.py", line 1203, in visit_table DropTable(table)._invoke_with(self.connection) File "\.venv\lib\site-packages\sqlalchemy\sql\ddl.py", line 314, in _invoke_with return bind.execute(self) File "\.venv\lib\site-packages\sqlalchemy\engine\base.py", line 1416, in execute return meth( File "\.venv\lib\site-packages\sqlalchemy\sql\ddl.py", line 180, in _execute_on_connection return connection._execute_ddl( File "\.venv\lib\site-packages\sqlalchemy\engine\base.py", line 1527, in _execute_ddl ret = self._execute_context( File "\.venv\lib\site-packages\sqlalchemy\engine\base.py", line 1843, in _execute_context return self._exec_single_context( File "\.venv\lib\site-packages\sqlalchemy\engine\base.py", line 1983, in _exec_single_context self._handle_dbapi_exception( File "\.venv\lib\site-packages\sqlalchemy\engine\base.py", line 2352, in _handle_dbapi_exception raise sqlalchemy_exception.with_traceback(exc_info[2]) from e File "\.venv\lib\site-packages\sqlalchemy\engine\base.py", line 1980, in _exec_single_context result = context._setup_result_proxy() File "\.venv\lib\site-packages\sqlalchemy\engine\default.py", line 1838, in _setup_result_proxy strategy = _cursor.BufferedRowCursorFetchStrategy( File "\.venv\lib\site-packages\sqlalchemy\engine\cursor.py", line 1188, in __init__ self._rowbuffer = collections.deque(dbapi_cursor.fetchmany(1)) sqlalchemy.exc.ProgrammingError: (pyodbc.ProgrammingError) No results. Previous SQL was not a query. [SQL: DROP TABLE mygrc.mygrc_3ps_inherent_risk]
之后我尝试开启自动提交模式来执行删表操作,代码如下:
logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG) log.info(f"Dropping Table: mygrc.{table_name}") with dbEngine.connect().execution_options(isolation_level='AUTOCOMMIT') as connection: connection.execute(text(f'DROP TABLE IF EXISTS mygrc.{table_name}'))
结果还是没生效,从日志里能看到明明执行了DROP语句,但最后还是触发了ROLLBACK,即使已经开了AUTOCOMMIT。日志内容如下:
2025-03-28 10:07:56,802 - INFO - Dropping Table: mygrc.mygrc_3ps_inherent_risk 2025-03-28 10:07:58,279 INFO sqlalchemy.engine.Engine SELECT CAST(SERVERPROPERTY('ProductVersion') AS VARCHAR) 2025-03-28 10:07:58,279 - INFO - SELECT CAST(SERVERPROPERTY('ProductVersion') AS VARCHAR) 2025-03-28 10:07:58,279 INFO sqlalchemy.engine.Engine [raw sql] () 2025-03-28 10:07:58,279 - INFO - [raw sql] () 2025-03-28 10:07:58,416 INFO sqlalchemy.engine.Engine SELECT schema_name() 2025-03-28 10:07:58,416 - INFO - SELECT schema_name() 2025-03-28 10:07:58,416 INFO sqlalchemy.engine.Engine [generated in 0.00073s] () 2025-03-28 10:07:58,416 - INFO - [generated in 0.00073s] () 2025-03-28 10:07:58,822 INFO sqlalchemy.engine.Engine SELECT CAST('test max support' AS NVARCHAR(max)) 2025-03-28 10:07:58,822 - INFO - SELECT CAST('test max support' AS NVARCHAR(max)) 2025-03-28 10:07:58,823 INFO sqlalchemy.engine.Engine [generated in 0.00052s] () 2025-03-28 10:07:58,823 - INFO - [generated in 0.00052s] () 2025-03-28 10:07:58,958 INFO sqlalchemy.engine.Engine SELECT 1 FROM fn_listextendedproperty(default, default, default, default, default, default, default) 2025-03-28 10:07:58,958 - INFO - SELECT 1 FROM fn_listextendedproperty(default, default, default, default, default, default, default) 2025-03-28 10:07:58,959 INFO sqlalchemy.engine.Engine [generated in 0.00053s] () 2025-03-28 10:07:58,959 - INFO - [generated in 0.00053s] () 2025-03-28 10:08:35,716 INFO sqlalchemy.engine.Engine BEGIN (implicit; DBAPI should not BEGIN due to autocommit mode) 2025-03-28 10:08:35,716 - INFO - BEGIN (implicit; DBAPI should not BEGIN due to autocommit mode) 2025-03-28 10:08:35,716 INFO sqlalchemy.engine.Engine DROP TABLE IF EXISTS mygrc.mygrc_3ps_inherent_risk 2025-03-28 10:08:35,716 - INFO - DROP TABLE IF EXISTS mygrc.mygrc_3ps_inherent_risk 2025-03-28 10:08:35,717 INFO sqlalchemy.engine.Engine [generated in 0.00132s] () 2025-03-28 10:08:35,717 - INFO - [generated in 0.00132s] () 2025-03-28 10:08:43,022 INFO sqlalchemy.engine.Engine ROLLBACK using DBAPI connection.rollback(), DBAPI should ignore due to autocommit mode 2025-03-28 10:08:43,022 - INFO - ROLLBACK using DBAPI connection.rollback(), DBAPI should ignore due to autocommit mode
手动执行对应的SQL语句是完全没问题的,我的数据库账号也有足够的权限。有没有大佬能帮我分析下这是什么情况?
备注:内容来源于stack exchange,提问作者trevrobwhite
相关产品推荐
相关产品推荐

