使用 SQLAlchemy 执行查询时避免参数绑定

Ale*_*and 5 python binding sqlalchemy teradata executequery

我正在使用 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;
Run Code Online (Sandbox Code Playgroud)

此 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()
Run Code Online (Sandbox Code Playgroud)

:V_VAR遇到的问题是 SQLAlchemy 假设变量是一个应该随字典一起提供的参数。请参阅此处的文档: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})
Run Code Online (Sandbox Code Playgroud)

在当前配置中,它会触发错误消息:

2018-04-18 19:09:27,874 - migration_script - INFO - 在 UAT 环境中执行对象 DDL 语句。2018-04-18 19:09:27,875 - migration_script - ERROR - (sqlalchemy.exc.InvalidRequestError)绑定参数 'V_VAR' [SQL: "()\rUNIT_TEST_NEW_STORED_PROCEDURE:\rBEGIN\r DECLARE V_VAR需要一个值);\r SELECT 'Hello World!'\r INTO ?;\rEND;"] [参数:[{}]]

您是否知道一种避免此错误消息的方法,以便我上面的 DDL 语句正确执行?

Ilj*_*ilä 7

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;
"""
Run Code Online (Sandbox Code Playgroud)

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