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)
Другие вопросы по тегам