繁体   English   中英

SQLAlchemy WHERE IN单值(原始SQL)

[英]SQLAlchemy WHERE IN single value (raw SQL)

在执行检查多个值的原始SQL时,我遇到SQLAlchemy问题。

my_sess.execute(
        "SELECT * FROM table WHERE `key`='rating' AND uid IN :uids",
        params=dict(uids=some_list)
    ).fetchall()

此查询有两种情况,一种有效,另一种无效。 如果some_list = [1] ,它会抛出一个SQL错误,我接近语法错误) 但是如果some_list = [1, 2] ,查询会成功执行。

这会发生什么原因?

不,SQL参数只处理量值。 你必须在这里生成SQL; 如果您需要原始SQL,请使用:

statement = "SELECT * FROM table WHERE `key`='rating' AND uid IN ({})".format(
    ', '.join([':i{}'.format(i) for i in range(len(some_list))]))

my_sess.execute(
        statement, 
        params={'i{}'.format(i): v for i, v in enumerate(some_list)})
    ).fetchall()

例如,生成足够的参数以使用字符串格式保存some_list所有值,然后生成匹配参数以填充它们。

更好的方法是使用literal_column()对象为您完成所有生成:

from sqlalchemy.sql import literal_column

uid_in = literal_column('uid').in_(some_list)
statement = "SELECT * FROM able WHERE `key`='rating' AND {}".format(uid_in)

my_sess.execute(
        statement, 
        params={'uid_{}'.format(i): v for i, v in enumerate(some_list)})
    ).fetchall()

但是你可能只需要使用`sqlalchemy.sql.expression模块生成整个语句,因为这样可以更容易地支持多个数据库方言。

而且, uid_in对象已经保存了对绑定参数的正确值的引用; 而不是把它变成像我们做的一个字符串str.format()以上的动作,SQLAlchemy的将有实际的对象,加上相关的参数,你就不再需要产生params词典无论是

以下应该有效:

from sqlalchemy.sql import table, literal_column, select

tbl = table('table')
key_clause = literal_column('key') == 'rating'
uid_clause = literal_column('uid').in_(some_list)
my_sess.execute(select('*', key_clause & uid_clause, [tbl]))

其中sqlalchemy.sql.select()采用列规范(此处硬编码为* ),where子句(使用&生成SQL AND子句的两个子句生成)和可选择列表; 这里是你的一个sqlalchemy.sql.table()值。

快速演示:

>>> from sqlalchemy.sql import table, literal_column, select
>>> some_list = ['foo', 'bar']
>>> tbl = table('table')
>>> key_clause = literal_column('key') == 'rating'
>>> uid_clause = literal_column('uid').in_(some_list)
>>> print select('*', key_clause & uid_clause, [tbl])
SELECT * 
FROM "table" 
WHERE key = :key_1 AND uid IN (:uid_1, :uid_2)

但是从这一切生成的实际对象树也包含绑定参数的实际值,因此my_sess.execute()可以直接访问它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM