10

我正在尝试找到一种方法使 SQLAlchemy 生成以下形式的查询:

select * from t where (a,b) in ((a1,b1),(a2,b2));

这可能吗?

如果没有,关于模仿它的方法有什么建议吗?

4

4 回答 4

29

使用tuple_

keys = [(a1, b1), (a2, b2)]
session.query(T).filter(tuple_(T.a, T.b).in_(keys)).all()

http://docs.sqlalchemy.org/en/latest/core/sqlelement.html#sqlalchemy.sql.expression.tuple_

于 2011-07-17T15:48:17.307 回答
3

好吧,多亏了上面的 Hao Lian,我想出了一个实用但痛苦的解决方案。

假设我们有一个声明式的映射类,Clazz和一个list复合主键值的元组,values (编辑为使用更好的 (IMO) sql 生成样式):

从 sqlalchemy.sql.expression 导入文本,绑定参数
...
    def __gParams(self, f, vs, ts, bs):
        对于 enumerate(vs) 中的 j,v:
            关键 = f % (j+97)
            bs.append(bindparam(key, value=v, type_=ts[j]))
            产量 ':%s' % 键

    def __gRows(self, ts, values, bs):
        对于 i,vs in enumerate(values):
            f = '%%c%d' % i
            产量 '(%s)' % ', '.join(self.__gParams(f, vs, ts, bs))

    def __gKeys(self, k, ts):
        对于 k 中的 c:  
            ts.append(c.type)
            产量 str(c)

    def __makeSql(self,Clazz, values):
        t = []
        乙 = []
        返回文本(
                '(%s) in (%s)' % (
                    ', '.join(self.__gKeys(Clazz.__table__.primary_key,t)),
                    ', '.join(self.__gRows(t,values,b))),
                绑定参数=b)

此解决方案适用于复合或简单主键。col.in_(keys)不过,它可能比简单的主键慢一点。

我仍然对建议更好的方法来做到这一点感兴趣,但这种方式目前正在工作,并且性能明显优于or_(and_(conditions))方式或for key in keys: do_stuff(q.get(key))方式。

于 2009-06-04T16:25:35.730 回答
2

请参阅SQLAlchemy 0.6 中的tuple_ 构造

于 2010-04-01T21:51:20.820 回答
0

带有文本子句的简单无痛方法:

from sqlalchemy import text

keys  = [('a1', 'b1'), ('a2', 'b2')]
statement = text(f'SELECT t.* FROM table t WHERE (t.a, t.b) in :keys')
session.execute(statement, {'keys': tuple(keys)})

只需要确保键是元组对的数组。

于 2020-12-08T16:23:51.913 回答