如何使用Python/SQLAlchemy和MSSQL在一个SQL中执行多个插入/更新查询?

6yjfywim  于 2024-01-05  发布在  Python
关注(0)|答案(1)|浏览(406)

此问题在此处已有答案

pyodbc does not throw on SQL Server error(1个答案)
昨天就关门了。
我是Python和SQLAlchemy的新手,我正在尝试了解如何使用Python/SQLAlchemy在一个SQL中执行多个插入/更新查询:

要求在一个SQL中执行多个插入/更新:

  1. DECLARE @age INT = 160
  2. INSERT INTO TEST_TABLE VALUES ('QZ_TEST', @age + 1)
  3. INSERT INTO TEST_TABLE VALUES ('QZ_TEST', 'not a number')
  4. INSERT INTO ANOTHER_TABLE VALUES ('QZ_TEST', @age + 2)

字符串
要知道,这个查询看起来很难看,但我们确实有很多类似的查询。(我们使用的是一个大约20年前的遗留数据库)

Python程式码

  1. def OdbcEngineSA(driver, conn_str):
  2. def connect():
  3. return pyodbc.connect(conn_str, autocommit=True, timeout=120)
  4. return sqlalchemy.create_engine(driver + '://', creator=connect)
  5. def get_db_connection():
  6. return OdbcEngineSA('mssql', 'DSN=mssql;Server=server,15001;database=DEV;UID=user_abc;PWD=pw_')
  7. def main():
  8. db_connection = get_db_connection()
  9. sql = """
  10. DECLARE @age INT = 160
  11. INSERT INTO TEST_TABLE VALUES ('QZ_TEST', @age + 1)
  12. INSERT INTO TEST_TABLE VALUES ('QZ_TEST', 'not a number')
  13. INSERT INTO ANOTHER_TABLE VALUES ('QZ_TEST', @age + 2)
  14. """
  15. try:
  16. db_connection.execute(sql)
  17. db_connection.commit()
  18. logger.info('db updated')
  19. except Exception as e:
  20. logger.error('Exception captured as expected: %s', e)
  21. db_connection.rollback()


请注意

  1. INSERT INTO TEST_TABLE VALUES ('QZ_TEST', 'not a number')


如果我使用SQL客户端运行此单个查询,将触发错误:[S 0001][245]将varchar值“不是数字”转换为int数据类型时,转换失败。
我期待Python会捕获一个异常,但是,Python代码运行时没有任何异常。即使我用替换了SQL,Python也没有捕获任何异常:

  1. BEGIN TRY
  2. DECLARE @age INT = 160
  3. INSERT INTO TEST_TABLE VALUES ('QZ_TEST', @age + 1)
  4. INSERT INTO TEST_TABLE VALUES ('QZ_TEST', 'not a number')
  5. INSERT INTO ANOTHER_TABLE VALUES ('QZ_TEST', @age + 2)
  6. END TRY
  7. BEGIN CATCH
  8. DECLARE @ErrorMessage NVARCHAR(4000)
  9. DECLARE @ErrorSeverity INT
  10. DECLARE @ErrorState INT
  11. SELECT
  12. @ErrorMessage = ERROR_MESSAGE(),
  13. @ErrorSeverity = ERROR_SEVERITY(),
  14. @ErrorState = ERROR_STATE()
  15. RAISERROR (@ErrorMessage,
  16. @ErrorSeverity, -- Level 16
  17. @ErrorState
  18. )
  19. END CATCH

我的问题

  • 我是否使用了正确的方法来执行查询?
  • 如果我的代码没有问题,我如何从Python中捕获实际的SQL异常?
eaf3rand

eaf3rand1#

execute命令在准备语句时可能会遇到问题,因为它实际上是多个语句。对于您正在尝试做的事情,我相信您可能想看看executemany
https://github.com/mkleehammer/pyodbc/wiki/Cursor#executemanysql-paras
它采用了不同的形式,并将您的值绑定为列表中的元组。
祝你好运!

相关问题