Edu*_*uca 3 python mysql sqlalchemy
在执行检查多个值的原始SQL时,我遇到SQLAlchemy问题.
my_sess.execute(
"SELECT * FROM table WHERE `key`='rating' AND uid IN :uids",
params=dict(uids=some_list)
).fetchall()
Run Code Online (Sandbox Code Playgroud)
此查询有两种情况,一种有效,另一种无效.如果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()
Run Code Online (Sandbox Code Playgroud)
例如,生成足够的参数以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()
Run Code Online (Sandbox Code Playgroud)
但是你可能只需使用`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]))
Run Code Online (Sandbox Code Playgroud)
其中sqlalchemy.sql.select()采用列规格(这里硬编码到*),where子句(从两个子句产生具有&以生成SQL AND子句)和selectables的列表; 这是你的唯一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)
Run Code Online (Sandbox Code Playgroud)
但是从这一切生成的实际对象树也包含绑定参数的实际值,因此my_sess.execute()可以直接访问它们.