SQLAlchemy执行Oracle查询返回参数值而非脚本结果问题
问题:SQLAlchemy查询返回参数值而非预期的MAX结果
尝试使用SQLAlchemy 1.4查询Oracle数据库,执行SQL语句:
SELECT MAX(:created_date) FROM EXAMPLE_TABLE
预期返回datetime类型对象,但执行以下代码后,结果却是传入的:created_date参数值“blah”:
from sqlalchemy import create_engine as SQLAlchemyEngine from sqlalchemy import text as SQLAlchemyText with SQLAlchemyEngine("example").connect() as sqlalchemy_connection: with open(sql_script_path) as sql_script: sql_query = SQLAlchemyText(sql_script.read()) parameters = {"created_date": "blah"} result = connection.execute(sql_query, parameters) for row in result: print(row)
原因
你试图通过参数绑定指定MAX()函数的目标列,但SQLAlchemy不支持将参数绑定到列名、表名这类SQL标识符上——参数绑定仅适用于SQL语句中的值(比如WHERE id = :user_id里的:user_id)。
当你执行MAX(:created_date)时,:created_date会被直接替换为你传入的字符串"blah",最终执行的SQL实际是MAX('blah')。由于MAX()函数对单一字符串值的计算结果就是该值本身,所以查询返回"blah"。
SQLAlchemy官方文档对此有明确说明:
绑定列名与表名
SQL查询中无法绑定列名或表名。可通过拼接文本构建SQL语句,但需使用白名单或其他方式验证数据以避免SQL注入风险。
解决方法
如果需要动态指定MAX()的目标列,必须通过字符串拼接生成SQL,但一定要通过白名单验证确保列名合法,避免SQL注入风险:
from sqlalchemy import create_engine as SQLAlchemyEngine from sqlalchemy import text as SQLAlchemyText # 定义合法列名的白名单,仅允许已知的安全列名 allowed_columns = {"created_date", "updated_date", "record_date"} target_column = "created_date" # 验证列名合法性 if target_column not in allowed_columns: raise ValueError("非法的列名,存在SQL注入风险") with SQLAlchemyEngine("example").connect() as sqlalchemy_connection: # 安全拼接SQL语句 sql_query = SQLAlchemyText(f"SELECT MAX({target_column}) FROM EXAMPLE_TABLE") result = sqlalchemy_connection.execute(sql_query) for row in result: print(row)
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

