where()未按预期在sqlalchemy中处理参数

时间:2018-09-18 22:26:20

标签: python sql sqlite sqlalchemy

///

这将获得正确的表,但是由于某种原因,构造的查询不是人们期望的。以下是构造的查询

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" = ?

1 个答案:

答案 0 :(得分:1)

SQLAlchemy尽可能创建parameterized SQL queries

这意味着查询?子句中的WHERE只是一个占位符,将在执行查询时填充实际数据('F1')(然后将参数< em>绑定查询)。

确切的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'

还要注意该文档中的段落:

  

以上表格将在传递给SQL语句时呈现该SQL语句。   Python DBAPI,其中包含未绑定的参数   排队。 SQLAlchemy通常不对绑定参数进行字符串化,因为   这由Python DBAPI适当地处理,更不用说   绕过绑定参数可能是使用最广泛的   现代Web应用程序中的安全漏洞。

含义,参数化查询以及分别绑定到该参数的参数将像这样传递给Python DBAPI(如果需要,则为DB“驱动程序”),因为这是最高效,最安全的方式做事。您可以使用内联参数可视化查询,如上所示,但这并不是真正的问题。


相反,如果您要调试查询,则应该使用echo=True parameter for the engine:这将方便地记录参数化查询的执行时间,它们的绑定参数