如何使用 SQLAlchemy 获取与三元组条件列表匹配的行 [英] How to get rows which match a list of 3-tuples conditions with SQLAlchemy

查看:22
本文介绍了如何使用 SQLAlchemy 获取与三元组条件列表匹配的行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个三元组列表:

[(a, b, c), (d, e, f)]

我想从一个表中检索所有行,其中 3 列与元组匹配.对于这个例子,查询 WHERE 子句可能是这样的:

I want to retrieve all the rows from a table where 3 columns matches the tuples. FOr this example, the query WHERE clause could be something like this :

   (column_X = a AND column_Y = b AND column_Z = c)
OR (column_X = d AND column_Y = e AND column_Z = f)

如何使用 SQLAlchemy 创建这样的请求?就我而言,3 元组列表将包含数百个元素,我正在寻找最佳的可扩展解决方案.

How can I create such a request using SQLAlchemy ? In my case the 3-tuples list will contains hundred of elements, and I'm looking for the best scallable solution.

感谢您的帮助,

推荐答案

最简单的方法是使用 SQLAlchemy 提供的 tuple_ 函数:

Easiest way would be using SQLAlchemy-provided tuple_ function:

from sqlalchemy import tuple_

session.query(Foo).filter(tuple_(Foo.a, Foo.b, Foo.c).in_(items))

这适用于 PostgreSQL,但与 SQLite 不同.不确定其他数据库引擎.

This works with PostgreSQL, but breaks with SQLite. Not sure about other database engines.

幸运的是,有一个适用于所有数据库的解决方法.

Fortunately there's a workaround that should work on all databases.

首先用 and_ 表达式映射所有项目:

Start by mapping out all the items with the and_ expression:

conditions = (and_(c1=x, c2=y, c3=z) for (x, y, z) in items)

然后创建一个包含所有条件的 or_ 过滤器:

And then create an or_ filter that encloses all the conditions:

q.filter(or_(*conditions))

这是一个简单的例子:

#/usr/bin/env python
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer
from sqlalchemy.sql import and_, or_
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///')
session = sessionmaker(bind=engine)()
Base = declarative_base()

class Foo(Base):
    __tablename__ = 'foo'

    id = Column(Integer, primary_key=True)
    a = Column(Integer)
    b = Column(Integer)
    c = Column(Integer)

    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def __repr__(self):
        return '(%d %d %d)' % (self.a, self.b, self.c)

Base.metadata.create_all(engine)

session.add_all([Foo(1, 2, 3), Foo(3, 2, 1), Foo(3, 3, 3), Foo(1, 3, 4)])
session.commit()
items = ((1, 2, 3), (3, 3, 3))
conditions = (and_(Foo.a==x, Foo.b==y, Foo.c==z) for (x, y, z) in items)
q = session.query(Foo)
print q.all()
q = q.filter(or_(*conditions))
print q
print q.all()

输出:

$ python test.py 
[(1 2 3), (3 2 1), (3 3 3), (1 3 4)]
SELECT foo.id AS foo_id, foo.a AS foo_a, foo.b AS foo_b, foo.c AS foo_c 
FROM foo 
WHERE foo.a = :a_1 AND foo.b = :b_1 AND foo.c = :c_1 OR foo.a = :a_2 AND foo.b = :b_2 AND foo.c = :c_2
[(1 2 3), (3 3 3)]

这篇关于如何使用 SQLAlchemy 获取与三元组条件列表匹配的行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆