不,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()
object做所有的發電爲您提供:
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()
可以直接訪問這些。
儘管我明白你的答案的作用,並且打印'statement'變量產生了一個有效的SQL,我在調用'execute'方法時得到'AttributeError:'list'對象沒有屬性'keys'。 –
@EduardLuca:啊,我從不使用'session.execute()',它確實只支持命名參數。將更新。 –
@EduardLuca:但是,您真的應該考慮使用SQLAlchemy的核心功能來生成SQL。我敢打賭,它也可以處理「一代人」。 –