【问题标题】:Sqlalchemy complex in_ clause with tuple in list of tuples元组列表中带有元组的 Sqlalchemy 复杂 in_ 子句
【发布时间】:2010-10-31 04:44:49
【问题描述】:

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

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

这可能吗?

如果没有,有什么模仿它的建议吗?

【问题讨论】:

    标签: python sql sqlalchemy


    【解决方案1】:

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

    【讨论】:

    • Warning 警告(来自 sqlalchemy 文档):复合 IN 结构并非所有后端都支持,目前已知可在 PostgreSQL 和 MySQL 上工作,但不适用于 SQLite。调用此类表达式时,不受支持的后端将引发 DBAPIError 的子类。
    • 有人想评论一下终端.all()做了什么吗?
    • @johnDanger, .all() 返回所有符合过滤条件的条目。或者,您可以调用 .first() 来返回第一个结果。还有其他功能。您可以在此处查看查询 API:docs.sqlalchemy.org/en/14/orm/query.html
    【解决方案2】:

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

    假设我们有一个声明式映射类 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)) 方式。

    【讨论】:

      【解决方案3】:

      查看 SQLAlchemy 0.6 中的 tuple_ construct

      【讨论】:

        【解决方案4】:

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

        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)})
        

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

        【讨论】:

          猜你喜欢
          • 2018-12-11
          • 1970-01-01
          • 2021-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-04
          相关资源
          最近更新 更多