Sqlalchemy complex in_子句与元组列表中的元组

时间:2009-06-04 01:40:38

标签: python sql sqlalchemy

我正试图找到一种方法让SQLAlchemy生成以下表单的查询:

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

这可能吗?

如果没有,有关模仿它的方法的任何建议吗?

4 个答案:

答案 0 :(得分:21)

使用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_

答案 1 :(得分:3)

好吧,多亏了上面的郝莲,我提出了一个功能性的,如果痛苦的解决方案。

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

from sqlalchemy.sql.expression import text,bindparam
...
    def __gParams(self, f, vs, ts, bs):
        for j,v in enumerate(vs):
            key = f % (j+97)
            bs.append(bindparam(key, value=v, type_=ts[j]))
            yield ':%s' % key

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

    def __gKeys(self, k, ts):
        for c in k:  
            ts.append(c.type)
            yield str(c)

    def __makeSql(self,Clazz, values):
        t = []
        b = []
        return text(
                '(%s) in (%s)' % (
                    ', '.join(self.__gKeys(Clazz.__table__.primary_key,t)),
                    ', '.join(self.__gRows(t,values,b))),
                bindparams=b)

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

我仍然对提供更好方法的建议感兴趣,但这种方式目前正在运行,并且明显优于or_(and_(conditions))方式或for key in keys: do_stuff(q.get(key))方式。

答案 2 :(得分:2)

请参阅SQLAlchemy 0.6中的tuple_ construct

答案 3 :(得分:0)

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

<style>
#not-working {
  font-family: Lobster, monospace;
  font-size: 45px;
  text-align: center;             
  color: white;
}
body{
  background-image: url("https://wallpaperaccess.com/full/17520.jpg");
}
</style>
<p id="not-working"> hello world</p>

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