如何使用sqlalchemy在子句中编写多列

vvl*_*rov 8 python mysql sqlalchemy

请建议是否有使用SQLAlchemy在子句中编写查询多列的方法?

以下是实际查询的示例:

SELECT  url FROM pages WHERE (url_crc, url) IN ((2752937066, 'http://members.aye.net/~gharris/blog/'), (3799762538, 'http://www.coxandforkum.com/'));
Run Code Online (Sandbox Code Playgroud)

我有一个表有两列主键,我希望避免添加一个键只是用作索引.

PS我正在使用mysql DB.

更新:此查询将用于批处理 - 因此我需要将几百对放入in子句中.使用IN子句方法,我希望知道我可以在一个查询中绑定多少对的固定限制.就像Oracle默认拥有1000枚枚举限制一样.

使用AND/OR组合可能受chars中查询的长度限制.哪个是可变的,不太可预测的.

小智 10

假设您已定义模型Page,这里是一个使用示例tuple_:

keys = [
    (2752937066, 'http://members.aye.net/~gharris/blog/'),
    (3799762538, 'http://www.coxandforkum.com/')
]

select([
    Page.url
]).select_from(
    Page
).where(
    tuple_(Page.url_crc, Page.url).in_(keys)
)
Run Code Online (Sandbox Code Playgroud)

或者,使用查询API:

session.query(Page.url).filter(tuple_(Page.url_crc, Page.url).in_(keys))
Run Code Online (Sandbox Code Playgroud)


vvl*_*rov 0

我最终使用了基于 test() 的解决方案:使用命名绑定变量生成“(a,b) in ((:a1, :b1), (:a2,:b2), ...)”并使用绑定生成字典变量的值。

params = {}
for counter, r in enumerate(records):
    a_param = "a%s" % counter
    params[a_param] = r['a']
    b_param = "b%s" % counter
    params[b_param] = r['b']
    pair_text = "(:%s,:%s)" % (a_param, b_param)
    enum_pairs.append(pair_text)
multicol_in_enumeration = ','.join(enum_pairs)
multicol_in_clause = text(
    " (a,b) in (" + multicol_in_enumeration + ")")
q = session.query(Table.id, Table.a,
                            Table.b).filter(multicol_in_clause).params(params)
Run Code Online (Sandbox Code Playgroud)

我考虑过使用 mysql upserts 的另一个选择,但这将使整个包含对于其他数据库引擎来说更不那么可移植,然后使用多列 in 子句。

更新SQLAlchemy 具有可用于相同目的的sqlalchemy.sql.expression.tuple_(*clauses, **kw)构造。(我还没试过)