【问题标题】:Avoid Parameter Binding When Executing Query with SQLAlchemy使用 SQLAlchemy 执行查询时避免参数绑定
【发布时间】:2018-09-28 21:08:27
【问题描述】:

我正在使用 SQLALchemy 在 Teradata 上执行查询。我执行的查询之一是替换存储过程的 DDL 语句:

REPLACE PROCEDURE DEV_MIGRATION_TOOL.UNIT_TEST_NEW_STORED_PROCEDURE()
UNIT_TEST_NEW_STORED_PROCEDURE:
BEGIN
    DECLARE V_VAR VARCHAR(50);
    SELECT 'Hello World!'
    INTO :V_VAR;
END;

这个SQL语句被赋值给一个变量query,由SQLALchemy用会话执行方法执行:

def execute_sql_statement(self, query):
    """Generic method to execute a SQL statement on target environment."""
    self.target_environment.db_session.execute(query)
    self.target_environment.db_session.commit()

我遇到的问题是 SQLAlchemy 假设 :V_VAR 变量是一个应该与字典一起提供的参数。请参阅此处的文档:http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.execute

result = session.execute("SELECT * FROM user WHERE id=:param", {"param":5})

在当前配置下,触发错误信息:

2018-04-18 19:09:27,874 - 迁移脚本 - 信息 - 执行对象 DDL 关于 UAT 环境的声明。 2018-04-18 19:09:27,875 - migration_script - 错误 - (sqlalchemy.exc.InvalidRequestError) A 绑定参数“V_VAR”需要值 [SQL: "()\rUNIT_TEST_NEW_STORED_PROCEDURE:\rBEGIN\r DECLARE V_VAR VARCHAR(50);\r SELECT 'Hello World!'\r INTO ?;\rEND;"] [参数:[{}]]

您是否知道避免此错误消息的方法,以便我上面的 DDL 语句执行时不会出错?

【问题讨论】:

    标签: python binding sqlalchemy teradata executequery


    【解决方案1】:

    Session.execute() 解释纯 SQL 字符串,就像在 text() 构造中传递一样。因此,您必须转义任何您不希望被解释为开始占位符的冒号:

    对于需要逐字冒号的 SQL 语句,例如在行内字符串中,使用反斜杠转义

    所以你的 DDL 语句 query 应该是:

    """
    REPLACE PROCEDURE DEV_MIGRATION_TOOL.UNIT_TEST_NEW_STORED_PROCEDURE()
    UNIT_TEST_NEW_STORED_PROCEDURE:
    BEGIN
        DECLARE V_VAR VARCHAR(50);
        SELECT 'Hello World!'
        INTO \\:V_VAR;
    END;
    """
    

    请注意,反斜杠是故意正确转义的。如果不使用原始字符串文字,较新版本的 Python 将为无效的转义序列(例如 "\:")生成 SyntaxWarnings。

    【讨论】:

      猜你喜欢
      • 2014-06-06
      • 1970-01-01
      • 2023-03-26
      • 2015-07-22
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 2014-05-12
      • 1970-01-01
      相关资源
      最近更新 更多