python - 在 Sqlalchemy/Postgres 中使用绑定(bind)参数执行 WHERE IN

标签 python postgresql sqlalchemy

我尝试使用 Sqlalchemy 和 Postges 高效地执行 SELECT ... WHERE id IN (1,2,3)

如果我做一个简单的选择:

s.query(Model).filter(Model.id.in_([1,2,3])).all()

Sqlalchemy 运行此查询:

SELECT model.id AS model_id FROM model 
WHERE model.id IN (%(id_1)s, %(id_2)s, %(id_3)s)
{'id_1': 1, 'id_2': 2, 'id_3': 3}

当数组变长时,这是无效的。这也不适用于烘焙查询。

知道 Postgres 支持元组作为参数,我尝试使用绑定(bind)参数将数组/元组直接放入参数部分:

s.query(Model)
 .filter(Model.id.in_(bindparam('my_tuple')))
 .params(my_tuple=(1,2,3)).all()    

不幸的是,Sqlalchemy 不接受 in_ 中的 bindparam:

sqlalchemy.exc.InvalidRequestError: 
    in_() accepts either a list of expressions or a selectable:
        BindParameter('my_tuple', None, type_=NullType())

所以我试图以某种方式欺骗 Sqlalchemy 以接受 bindparam
扩展 BindParam 类我能够这样做:

class TupleBindParameter(BindParameter, Selectable):
    pass

s.query(Model)
 .filter(Model.id.in_(TupleBindParameter('my_tuple')))
 .params(my_tuple=(1,2,3)).all()

现在我得到了我想要的:

SELECT model.id AS model_id FROM model 
WHERE model.id IN %(my_tuple)s
{'my_tuple': (1, 2, 3)}

这个解决方案对我来说似乎有点老套。是否有官方方法让 Sqlalchemy 做同样的事情?

--

重现我的示例的设置非常简单:

Base = declarative_base()    
class Model(Base):
    __tablename__ = 'model'
    id = Column(Integer, primary_key=True)
    def __init__(self, id): self.id = id

engine = create_engine('postgres://x:x@localhost/x')    
Base.metadata.create_all(bind=engine)

Session = sessionmaker(bind=engine)
s = Session()
s.add_all([Model(1), Model(2), Model(4)])
s.commit()

最佳答案

使用op('IN')

s.query(Model)
 .filter(Model.id.op('IN')(bindparam('my_tuple')))
 .params(my_tuple=(1,2,3)).all()

参见 this issue

关于python - 在 Sqlalchemy/Postgres 中使用绑定(bind)参数执行 WHERE IN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44022209/

相关文章:

sql - 扩展现有的 PostgreSQL 类型

sql - PostgreSQL 中的窗口函数

python - SQLAlchemy 在合并上设置索引

python - SymPy 中符号概率的期望值

python - 如何在 Python 中创建递增的文件名?

python - 多个数组的绘图

sql - PostgreSQL:如何有效地更改 psql 中的多个列?

python - SQLAlchemy插入,更新前提条件(一致性检查)

python - sqlalchemy.exc.ProgrammingError : (psycopg2. ProgrammingError) ":"处或附近的语法错误

python - 在循环中绘制图形