使用 SQLAlchemy 执行查询时避免参数绑定
Avoid Parameter Binding When Executing Query with SQLAlchemy
我正在使用 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 - Execute object DDL
statement on UAT environment. 2018-04-18 19:09:27,875 -
migration_script - ERROR - (sqlalchemy.exc.InvalidRequestError) A
value is required for bind parameter 'V_VAR' [SQL:
"()\rUNIT_TEST_NEW_STORED_PROCEDURE:\rBEGIN\r DECLARE V_VAR
VARCHAR(50);\r SELECT 'Hello World!'\r INTO ?;\rEND;"]
[parameters: [{}]]
您是否知道一种避免此错误消息的方法,以便我上面的 DDL 语句无误地执行?
Session.execute()
interprets plain SQL strings as if passed in a text()
构造。因此,您必须转义任何您不想解释为开始占位符的冒号:
For SQL statements where a colon is required verbatim, as within an inline string, use a backslash to escape
所以你的 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 的较新版本将为无效的转义序列生成 SyntaxWarning
s,例如 "\:"
,如果不使用原始字符串文字。
我正在使用 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 - Execute object DDL statement on UAT environment. 2018-04-18 19:09:27,875 - migration_script - ERROR - (sqlalchemy.exc.InvalidRequestError) A value is required for bind parameter 'V_VAR' [SQL: "()\rUNIT_TEST_NEW_STORED_PROCEDURE:\rBEGIN\r DECLARE V_VAR VARCHAR(50);\r SELECT 'Hello World!'\r INTO ?;\rEND;"] [parameters: [{}]]
您是否知道一种避免此错误消息的方法,以便我上面的 DDL 语句无误地执行?
Session.execute()
interprets plain SQL strings as if passed in a text()
构造。因此,您必须转义任何您不想解释为开始占位符的冒号:
For SQL statements where a colon is required verbatim, as within an inline string, use a backslash to escape
所以你的 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 的较新版本将为无效的转义序列生成 SyntaxWarning
s,例如 "\:"
,如果不使用原始字符串文字。