【问题标题】:How to order data in sqlalchemy by list如何按列表对sqlalchemy中的数据进行排序
【发布时间】:2014-04-30 07:00:42
【问题描述】:

我有来自外部 postgresql 数据库的 ID 列表。

A = [1,2,3,4,5,6,7,98,0]

我会使用 SQLAlchemy 对数据库进行查询,但我会按 A 列表对 postgresql 中的数据进行排序。

我已阅读大量文档,但找不到任何建议。

所以,最后我会:

results = session.query(user).limit(20).offset(10).order_by(A)

干杯

更新:

我找到了解决方案,它没有我预期的那么好,但效果很好。无论如何,如果您知道更好的解决方案,请告诉我!

ids = ','.join([str(i) for i in A])
results = session.query(user).filter(user.id.in_(A)).\
limit(20).offset(10).\
order_by(" position(CONCAT(',',users.id::text,',') in ',{0},'.format(ids)")

【问题讨论】:

  • 顺便说一句。我知道 postgresql 支持“连接值”stackoverflow.com/questions/866465/…,但无法弄清楚如何使用 sqlalchemy 实现这一点
  • 我很好奇这样订购的原因,您介意详细说明吗?

标签: python sql postgresql sqlalchemy


【解决方案1】:

如果您不一定需要在 SQL 中执行此操作,您可以直接在 python 中简单地对返回的对象列表进行排序。

示例(使用python的sorted函数)

results = session.query(user).filter(user.id.in_(A)).all()
results = sorted(results, key=lambda o: A.index(o.id))

【讨论】:

    【解决方案2】:

    这是使用 SQLAlchemy 大小写表达式进行排序的示例。

    from sqlalchemy import case
    
    from core.orm import session
    from core.orm import models
    
    query = session.query(models.Model)
    
    ids_list = [1, 2, 4, 3, 5]
    
    # order query by index of id in `id_list`
    
    id_ordering = case(
        {_id: index for index, _id in enumerate(ids_list)},
        value=models.Model.id
    )
    
    # order 
    query = query.order_by(id_ordering)
    

    【讨论】:

    • 在内部,该语法构成了这个 SQL 语句 ORDER BY CASE Table.column WHEN index THEN _id。对我很有帮助。
    【解决方案3】:

    你可以试试:

    results = session.query(user).limit(20).offset(10).order_by(*A)
    

    【讨论】:

      【解决方案4】:

      另一种方法是创建另一个帮助表,其中包含每个 user.id 的订单位置、加入它和订单:

      A = [1,2,3,4,5,6,7,98,0]
      stmt = " UNION ALL ".join( 'SELECT {0} AS user_id, {1} AS order_id'.format(uid, row)
              for row, uid in enumerate(A))
      ordq = text(stmt).columns(user_id=Integer, order_id=Integer).alias("t")
      results = session.query(user).join(ordq, user.id == ordq.c.user_id).order_by(ordq.c.order_id).all()
      

      我无法判断这是否比您的版本更好,但它至少应该是非 RDBMS 特定的。

      【讨论】:

      • 嗯,我确实考虑过这种方式,但可能它应该很慢,因为您必须在数据库中再进行一项操作,再进行一次连接,而不仅仅是一次查询。
      • 不需要在数据库中进行操作,因为您在内存中执行此操作(如代码所示)。会不会很慢 - 很大程度上取决于此 select 语句的长度。
      猜你喜欢
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 2012-08-31
      • 1970-01-01
      • 2022-12-18
      • 2020-01-23
      • 2017-11-24
      • 1970-01-01
      相关资源
      最近更新 更多