Python: простой порядок с помощью Pony ORM
Я пытаюсь реализовать простой выбор с агрегацией order_by в pony orm:
Итак, я попытался способами: первый способ поднять сообщение об ошибке:
sel = select((f.Name, f.id) for f in Firma).order_by(Firma.Name)
Таким образом, я получаю сообщение об ошибке от python: "NotImplementedError: Упорядочение по атрибутам ограничено запросами, которые возвращают простой список объектов. Попробуйте использовать другие формы упорядочения (по номерам элементов кортежа или полномасштабному лямбда-выражению)"
Второй способ, если выборка по порядку работает нормально, но вставка в мой словарь разрушает порядок выбора.
for f in Firma.select(lambda f: f.Name) \
.order_by((Firma.Name)):
dic[f.Name] = f.id
print ("=== f.Name", f.Name)
dic[f.Name] = f.id
print(" === dic[f.Name]", dic[f.Name])
Результат следующий:
=== f.Name A
=== dic[f.Name] 10
=== f.Name B
=== dic[f.Name] 11
=== f.Name C
=== dic[f.Name] 12
=== f.Name Neckermann
=== dic[f.Name] 7
=== f.Name Otto
=== dic[f.Name] 6
=== f.Name Quelle
=== dic[f.Name] 3
=== f.Name Testfirma
=== dic[f.Name] 9
=== f.Name The Pearlfactory
=== dic[f.Name] 8
Но словарь это:
dic {'Testfirma': 9, 'Quelle': 3, 'C': 12, 'The Pearlfactory': 8, 'B': 11, 'Otto': 6, 'A': 10, 'Neckermann': 7}
Теперь вопросы: как я могу использовать первый способ агрегирования order_by без этого сообщения об ошибке. Или, Как я могу поместить значения фирменного идентификатора и названия фирмы в моем словаре в отсортированном soccesion
Я надеюсь, что кто-то может понять мой ужасный английский;)
Привет
niesel
1 ответ
Что касается вашего первого вопроса, если запрос выбирает кортежи, вы можете заказать его, указав номер элемента кортежа:
query = select((f.Name, f.id) for f in Firma).order_by(1)
Вот, 1
означает "сортировать по первому элементу кортежа (то есть по Name
) в порядке возрастания ". Если вы укажете, скажем, -2
вместо этого это будет означать "сортировать по второму элементу кортежа (то есть id
) в порядке убывания ".
Другой способ сделать то же самое - указать лямбда-функцию в order_by
раздел:
query = select((f.Name, f.id) for f in Firma).order_by(lambda: f.Name)
или, например:
query = select((f.Name, f.id) for f in Firma).order_by(lambda: desc(f.id))
Обратите внимание, что я использую лямбда-функцию без каких-либо аргументов. В этой форме f
внутри лямбда будет ссылаться на переменную f
внутри выражения генератора. Имейте в виду, что IDE не понимает этот синтаксис и может выделить его как ошибку, но код на самом деле правильный.
Ваш запрос с лямбда-функцией выглядит некорректно:
Firma.select(lambda f: f.Name).order_by((Firma.Name))
В этом запросе lambda
внутри select
используется для фильтрации, он просто фильтрует объекты, имя которых не пусто.
Что касается второго вопроса, то в Python словари неупорядочены. Если вы хотите сохранить порядок элементов, вы не должны держать их в словаре. Вместо этого используйте список:
query = select((f.Name, f.id) for f in Firma).order_by(1)
name_id_pairs = query[:] # retrieve result list from a query
# another form: name_id_pairs = list(query)
for name, id in name_id_pairs:
print('Name:', name, ', id:', id)
Если вся ваша обработка данных происходит внутри db_session
(что рекомендуется), вы можете извлекать объекты вместо кортежей из запроса:
query = select(f for f in Firma).order_by(lambda: f.name)
firms = list(query)
for f in firms:
print('Name:', f.name, ', id:', f.id)