2015-03-28 16 views
1

Я использую этот запросSQLAlchemy получить результаты в том же порядке,

users = User.query.filter(User.id.in_(user_ids)).all() 

Я хочу, чтобы получить users в том же порядке, как и в user_ids. В любом случае, я могу сделать это непосредственно в запросе или мне придется сортировать его снова? Кроме того, если мне нужно снова его отсортировать, то каков питонический способ сортировки списков объектов на основе другого списка идентификаторов.

+0

Ну, я нашел питоновский способ его сортировки. users.sort (key = lambda x: user_ids.index (x.id)), но все еще ищет, возможно ли это сделать непосредственно в запросе – Waseem

+0

Итак, у вас есть ваши 'user_ids' в произвольном порядке (не обязательно отсортированные) и вы хотите заказать результаты SQL на основе столбца 'User.id' и списка' user_ids'? То есть а не просто 'ORDER BY" User.id "'? –

+0

Я видел, что DB не возвращает мне результаты в порядке, я даю ему список user_id. Итак, да, я хочу сортировать результаты на основе списка used_ids, а не ORDER BY «User.id» – Waseem

ответ

1

Это очень возможно, хотя и некрасиво, с PostgreSQL 9.4+ и SQLAlchemy 0.9.7+. В основном мы строим карту ид -> порядковый, а затем использовать оператор JSONB -> найти порядковый номер для каждого идентификатора пользователя (-> требует TEXT для 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))