where() 不按 sqlalchemy 中的预期处理参数
Posted
技术标签:
【中文标题】where() 不按 sqlalchemy 中的预期处理参数【英文标题】:where() does not process parameters as expected in sqlalchemy 【发布时间】:2018-09-18 22:26:20 【问题描述】:table = engine.getFTable();
dBtable = table;
query = select([dBtable.c.id]).where( dBtable.c.FName == 'F1' );
print(query);
这得到了正确的表,但由于某种原因,构造的查询不是人们所期望的。以下是构造的查询
SELECT "FList".id
FROM "FList"
WHERE "FList"."FName" = ?
而不是
SELECT "FList".id
FROM "FList"
WHERE "FList"."FName" = 'F1'
【问题讨论】:
【参考方案1】:SQLAlchemy 尽可能创建parameterized SQL queries。
这意味着您的查询中的?
WHERE
子句只是一个占位符,在执行查询时将用实际数据 ('F1'
) 填充(然后将参数绑定 到查询)。
确切的syntax of the bound parameter placeholder 取决于您使用的 SQL 方言(PostgreSQL、mysql、...)。有些使用?
,有些支持:user_id
等命名参数。
您可以通过编译该查询对象并显示它的参数来查看将要填写的参数:
>>> query = select([table.c.userid]).where(table.c.userid == 'lukas.graf')
>>> print query
SELECT users.userid
FROM users
WHERE users.userid = :userid_1 <---- bind parameter placeholder
>>> compiled = query.compile()
>>> print compiled.params
u'userid_1': 'lukas.graf'
SQLAlchemy documentation 解释了如何将 SQL 表达式呈现为字符串,如果您需要调试它们:
>>> from sqlalchemy.dialects import postgresql
>>>
>>> query = select([table.c.userid]).where(table.c.userid == 'lukas.graf')
>>> compiled = query.compile(dialect=postgresql.dialect(), compile_kwargs="literal_binds": True)
>>> print compiled
SELECT users.userid
FROM users
WHERE users.userid = 'lukas.graf'
还要注意该文档中的段落:
上述表格将在传递给 Python DBAPI,其中包括未呈现绑定参数 排队。 SQLAlchemy 通常不会对绑定参数进行字符串化,因为 这由 Python DBAPI 适当处理,更不用说 绕过绑定参数可能是最广泛利用的 现代 Web 应用程序中的安全漏洞。
意思是,参数化查询以及单独绑定到它的参数,将像这样传递给 Python DBAPI(如果您愿意的话,是 DB“驱动程序”),因为这是最高效和最安全的方式做事。您可以使用如上所示的内联参数来可视化查询,但这并不是真正的实际情况。
相反,如果您正在调试您的查询,您更应该使用echo=True
parameter for the engine:这将方便地记录参数化查询在执行时,和它们的绑定参数。
【讨论】:
以上是关于where() 不按 sqlalchemy 中的预期处理参数的主要内容,如果未能解决你的问题,请参考以下文章