【问题标题】:How to execute multiple insert/update queries in one SQL using Python/SQLAlchemy and MSSQL?如何使用 Python/SQLAlchemy 和 MSSQL 在一个 SQL 中执行多个插入/更新查询?
【发布时间】:2016-04-24 10:05:55
【问题描述】:

我是 python 和 SQLAlchemy 的新手,我正在尝试了解如何使用 Python/SQLAlchemy 在一个 SQL 中执行多个插入/更新查询:

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

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

知道这个查询看起来很难看,但我们确实有很多类似的查询。 (我们使用的是一个已有 20 年历史的旧数据库)

Python 代码

def OdbcEngineSA(driver, conn_str):
    def connect():
        return pyodbc.connect(conn_str, autocommit=True, timeout=120)
    return sqlalchemy.create_engine(driver + '://', creator=connect)

def get_db_connection():
    return OdbcEngineSA('mssql', 'DSN=mssql;Server=server,15001;database=DEV;UID=user_abc;PWD=pw_')

def main():
    db_connection = get_db_connection()
    sql = """
    DECLARE @age INT = 160
    INSERT INTO TEST_TABLE VALUES ('QZ_TEST', @age + 1)
    INSERT INTO TEST_TABLE VALUES ('QZ_TEST', 'not a number')
    INSERT INTO ANOTHER_TABLE VALUES ('QZ_TEST', @age + 2)
    """
    try:
        db_connection.execute(sql)
        db_connection.commit()
        logger.info('db updated')   
    except Exception as e:
        logger.error('Exception captured as expected: %s', e)
        db_connection.rollback()

请注意

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

如果我用我的 SQL 客户端运行这个单一的查询,将会触发一个错误: [S0001][245] 将 varchar 值“非数字”转换为数据类型 int 时转换失败。

我预计 Python 会捕获一个异常,但是,Python 代码运行时没有任何异常。即使我将 SQL 替换为

,Python 也没有捕获到异常
BEGIN TRY
        DECLARE @age INT = 160
        INSERT INTO TEST_TABLE VALUES ('QZ_TEST', @age + 1)
        INSERT INTO TEST_TABLE VALUES ('QZ_TEST', 'not a number')
        INSERT INTO ANOTHER_TABLE VALUES ('QZ_TEST', @age + 2)
END TRY
    BEGIN CATCH
        DECLARE @ErrorMessage NVARCHAR(4000)
        DECLARE @ErrorSeverity INT
        DECLARE @ErrorState INT

        SELECT 
            @ErrorMessage = ERROR_MESSAGE(),
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE()

        RAISERROR (@ErrorMessage,
                   @ErrorSeverity, -- Level 16
                   @ErrorState
                   )
    END CATCH

我的问题

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

【问题讨论】:

    标签: python sql-server exception sqlalchemy pyodbc


    【解决方案1】:

    execute 命令可能在准备您的语句时遇到问题,因为它实际上是多个语句。对于你想要做的事情,我相信你可能想看看executemany

    https://github.com/mkleehammer/pyodbc/wiki/Cursor#executemanysql-paras

    它采用不同的形式并将您的 INSERT 值绑定为列表中的元组。

    祝你好运!

    【讨论】:

    • 谢谢!我的理解是“executemany”是 ORM 模块的一项功能,但是,我使用原始 SQL 并尝试在一个查询中插入不同的表。你知道原始sql是否有'executemany/batch'吗?谢谢。
    猜你喜欢
    • 2022-11-03
    • 2014-06-26
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    相关资源
    最近更新 更多