Pony ORM und order_by Klausel

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Benutzeravatar
nieselfriem
User
Beiträge: 135
Registriert: Sonntag 13. Januar 2013, 16:00

Hallo,

ich versuche mit Pony ORM eine Selectionanfrage mit order by Klausel auszuführen. Dazu habe ich zwei Methoden auspropbiert:

Code: Alles auswählen

sel = select((f.Name, f.id) for f in Firma).order_by(Firma.Name)
Hier bekomme ich allerdings die Fehlermeldung:

[codebox=text file=Unbenannt.txt]"NotImplementedError: Ordering by attributes is limited to queries which return simple list of objects. Try use other forms of ordering (by tuple element numbers or by full-blown lambda expr)"[/code]

Dann habe ich eine weiter Variante ausprobiert:

Code: Alles auswählen

     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])
Hier passiert jedoch folgendes. Gibt man die Selection direkt aus, dann ist die Sortierung korrekt. Packt man aber die Ausgaben der Attribute in das Dictionary (dic[f.Name] = f.id), ist die Sortierung wieder "zerstört"

[codebox=text file=Unbenannt.txt]=== 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[/code]

Das erzeugte Dictionary:

Code: Alles auswählen

dic  {'Testfirma': 9, 'Quelle': 3, 'C': 12, 'The Pearlfactory': 8, 'B': 11, 'Otto': 6, 'A': 10, 'Neckermann': 7}
Ich weiß nicht, wie ich das Gesamtergebnis des zweiten Lösungsansatzes geordnet in mein Dictionary bekomme.


Edit:

Ich habe noch was herausgefunden. Das Problem scheint nicht die Selectanweisung zu sein, sondern eher das Dictionray:

Folgender Code ergibt die unten stehende Ausgabe:

Code: Alles auswählen

sel = select((f.Name, f.id) for f in Firma).order_by(1, -2)
....
for selectin in sel:
     print("selectin: ", selectin)
     firm_dic[selectin[0]] = selectin[1]
     print("firm_dic in for", firm_dic)
[codebox=text file=Unbenannt.txt]
f.Name |f.id
----------------+----
A |10
B |11
C |12
Neckermann |7
Otto |6
Quelle |3
Testfirma |9
The Pearlfactory|8

selectin: ('A', 10)
firm_dic in for {'A': 10}
selectin: ('B', 11)
firm_dic in for {'A': 10, 'B': 11}
selectin: ('C', 12)
firm_dic in for {'C': 12, 'A': 10, 'B': 11}
selectin: ('Neckermann', 7)
firm_dic in for {'C': 12, 'A': 10, 'Neckermann': 7, 'B': 11}
selectin: ('Otto', 6)
firm_dic in for {'C': 12, 'A': 10, 'Otto': 6, 'Neckermann': 7, 'B': 11}
selectin: ('Quelle', 3)
firm_dic in for {'A': 10, 'Quelle': 3, 'B': 11, 'C': 12, 'Neckermann': 7, 'Otto': 6}
selectin: ('Testfirma', 9)
firm_dic in for {'A': 10, 'Testfirma': 9, 'Quelle': 3, 'B': 11, 'C': 12, 'Neckermann': 7, 'Otto': 6}
selectin: ('The Pearlfactory', 8)
firm_dic in for {'A': 10, 'Testfirma': 9, 'Quelle': 3, 'B': 11, 'C': 12, 'Neckermann': 7, 'The Pearlfactory': 8, 'Otto': 6}
[/code]

Wieso wird "A" und "B" richtig einsortiert, "C" auf einmal vorn angehangen und "Otto" auf einmal dazwischen?

VG niesel
Zuletzt geändert von nieselfriem am Freitag 28. April 2017, 13:27, insgesamt 1-mal geändert.
Liffi
User
Beiträge: 153
Registriert: Montag 1. Januar 2007, 17:23

Du bekommst die Daten vielleicht geordnet ins Dictionary, das Dictionary selber hat aber keine Ordnung. Vielleicht möchtest du hierfür einen anderen Datentyp verwenden.
Benutzeravatar
nieselfriem
User
Beiträge: 135
Registriert: Sonntag 13. Januar 2013, 16:00

Ich habe die Lösung:

Statt

Code: Alles auswählen

firm_dic = {}
...
verwende ich das OrderedDict

Code: Alles auswählen

firm_dic = collections.OrderedDict()

for f in Firma.select(lambda f: f.Name) \
   .order_by((Firma.Name)):
    firm_dic[f.Name] = f.id
und siehe da, es bleibt sortiert. :)

VG niesel
Antworten