Sqlalchemy 以相同的顺序获取结果
Sqlalchemy get results in the same order
我正在使用这个查询
users = User.query.filter(User.id.in_(user_ids)).all()
我想按 user_ids
中的相同顺序获取 users
。无论如何,我可以直接在查询中执行此操作,还是必须再次对其进行排序?另外,如果我必须再次对其进行排序,那么基于另一个 ID 列表对对象列表进行排序的 pythonic 方式是什么。
这是很有可能的,虽然很难看,使用 PostgreSQL 9.4+ 和 SQLAlchemy 0.9.7+。基本上我们构建一个 id -> ordinal 的映射,然后使用 JSONB ->
运算符找到每个用户 id 的序号(->
需要 TEXT
for JSON键
from sqlalchemy.sql.postgresql import JSONB, TEXT
from sqlalchemy.sql import cast
id_order = { str(v): k for k, v in enumerate(user_ids) }
users = User.query.filter(User.id.in_(user_ids)).\
order_by(cast(id_order, JSONB)[cast(User.id, TEXT)])
这将创建类似于
的SQL ORDER BY
ORDER BY CAST('{"1": 2, "3": 0, "2": 1}' AS JSONB) ->
CAST(user.id AS TEXT)
对于其他数据库,只需在客户端对其进行排序 - 虽然这意味着您无法浏览结果。
客户端排序的高效代码是:
id_order = { v: k for k, v in enumerate(user_ids) }
users = sorted(users, key=lambda u: id_order.get(u.id))
我正在使用这个查询
users = User.query.filter(User.id.in_(user_ids)).all()
我想按 user_ids
中的相同顺序获取 users
。无论如何,我可以直接在查询中执行此操作,还是必须再次对其进行排序?另外,如果我必须再次对其进行排序,那么基于另一个 ID 列表对对象列表进行排序的 pythonic 方式是什么。
这是很有可能的,虽然很难看,使用 PostgreSQL 9.4+ 和 SQLAlchemy 0.9.7+。基本上我们构建一个 id -> ordinal 的映射,然后使用 JSONB ->
运算符找到每个用户 id 的序号(->
需要 TEXT
for JSON键
from sqlalchemy.sql.postgresql import JSONB, TEXT
from sqlalchemy.sql import cast
id_order = { str(v): k for k, v in enumerate(user_ids) }
users = User.query.filter(User.id.in_(user_ids)).\
order_by(cast(id_order, JSONB)[cast(User.id, TEXT)])
这将创建类似于
的SQL ORDER BYORDER BY CAST('{"1": 2, "3": 0, "2": 1}' AS JSONB) ->
CAST(user.id AS TEXT)
对于其他数据库,只需在客户端对其进行排序 - 虽然这意味着您无法浏览结果。
客户端排序的高效代码是:
id_order = { v: k for k, v in enumerate(user_ids) }
users = sorted(users, key=lambda u: id_order.get(u.id))