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

时间:2018-04-18 14:51:03

标签: 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;

此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 - migration_script - INFO - 执行对象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 \ nDECLARE V_VAR   VARCHAR(50); \ r \ n选择' Hello World!' \ r \ n INTO ?; \ rEND;"]   [参数:[{}]]

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

1 个答案:

答案 0 :(得分:2)

Session.execute()解释纯SQL字符串,就好像在text()构造中传递一样。由于你必须逃避任何你不想解释为开始占位符的冒号:

  

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

请参阅:http://docs.sqlalchemy.org/en/latest/core/sqlelement.html#sqlalchemy.sql.expression.text

所以你的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;
"""