ORM select().distinct()

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mechanicalStore
User
Beiträge: 135
Registriert: Dienstag 29. Dezember 2009, 00:09

Hallo,

Habe Probleme bei der abfrage mit der distinct() methode. In der Objektstruktur sind viele Attribute enthalten, die QListView zeigt nur point_name an (funktioniert auch):

Code: Alles auswählen

   def data(self, index, role):
        if role == Qt.ItemDataRole.DisplayRole or role == Qt.ItemDataRole.EditRole:
            return self._measure_point_data[index.row()].point_name
Da es davon jeweils mehr als nur einen Eintrag gibt, wollte ich das mit distinct() filtern. Hat aber keinerlei Wirkung:

Code: Alles auswählen

    @classmethod
    def get_all_objects_by_measuring_id(cls, session, measuring_id):
        stmt = select(cls).distinct(cls.point_name).where(cls.measuring_id == measuring_id)
        print(stmt)
        result = session.execute(stmt).scalars().all()
        return sorted(result, key=lambda x: int(x.point_name[1:]), reverse=False)
Ausgabe des print:

Code: Alles auswählen

SELECT DISTINCT part_measuring_piece.id, part_measuring_piece.measuring_id, part_measuring_piece.point_name, part_measuring_piece.point_type, .....
FROM part_measuring_piece 
WHERE part_measuring_piece.measuring_id = :measuring_id_1
Benutzeravatar
sparrow
User
Beiträge: 4219
Registriert: Freitag 17. April 2009, 10:28

Welches ORM?
mechanicalStore
User
Beiträge: 135
Registriert: Dienstag 29. Dezember 2009, 00:09

sparrow hat geschrieben: Sonntag 28. April 2024, 14:27Welches ORM?
SQLAlchemy
Benutzeravatar
sparrow
User
Beiträge: 4219
Registriert: Freitag 17. April 2009, 10:28

Es gibt Datenbanken (wie postgres), die können Distinct unabhängig von den selekten Feldern.
Die von dir benutzte unterstützt das entweder nicht - oder SQLAlchemy wendet den falschen Dialekt an.
"Distinct" sorgt dafür, dass es keine Doppelten Datensätze gibt. Entsprechend müssen die Felder so eingeschränkt werden, dass ihre Kombination auch die entsprechenden Doppelungen enthält. Du selektierst aber alle Felder - und die sind offensichtlich in ihrer Kombination jeweils einzigartig.

Du musst also die Auswahl auf die Felder einschränken, die du tatsächlich verwendest.

Was machst du da eigentlich für seltsame Sachen mit der Sortierung? Das erste Zeichen abschneiden, in eine Ganzzahl umwandeln und dann sortieren?
mechanicalStore
User
Beiträge: 135
Registriert: Dienstag 29. Dezember 2009, 00:09

sparrow hat geschrieben: Sonntag 28. April 2024, 17:36 Es gibt Datenbanken (wie postgres), die können Distinct unabhängig von den selekten Feldern.
Die von dir benutzte unterstützt das entweder nicht - oder SQLAlchemy wendet den falschen Dialekt an.
Es ist SQLite
Du musst also die Auswahl auf die Felder einschränken, die du tatsächlich verwendest.
Ok, das funktioniert so jetzt. Ich dachte, wenn ich den Parameter an distinct() mitgebe, dass dann alles eingeschränkt wird, obwohl in select() alles abgefragt wird. An die id des Objects komme ich so allerdings nicht mehr dran, da ich statt des Objects nur noch das eine Attribut als String zurück bekomme. Brauche ich in dem Fall aber auch nicht.
Was machst du da eigentlich für seltsame Sachen mit der Sortierung? Das erste Zeichen abschneiden, in eine Ganzzahl umwandeln und dann sortieren?
Ich sortiere Zeichenketten die aus "R" und einer Nummer bestehen. Dabei kommt mit order_by() folglich sowas wie "R1 R10 R100 R25 R200...." heraus. Ich will aber aufsteigend anhand der Zahl sortieren. Daher schneide ich das "R" ab und wandle den Rest nach int um.
Wenn es dazu eine bessere/logischere Lösung gibt, bin ich natürlich offen dafür.

Danke und Gruß
Benutzeravatar
__blackjack__
User
Beiträge: 13163
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das steht übrigens in der Dokumentation, dass a) das Argument von `distinct()` nur für PostgreSQL Sinn macht, und b) das es „deprecated“ ist. Sollte man also nicht mehr benutzen, auch mit PostgreSQL nicht.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
mechanicalStore
User
Beiträge: 135
Registriert: Dienstag 29. Dezember 2009, 00:09

__blackjack__ hat geschrieben: Sonntag 28. April 2024, 19:51 Das steht übrigens in der Dokumentation, dass a) das Argument von `distinct()` nur für PostgreSQL Sinn macht, und b) das es „deprecated“ ist. Sollte man also nicht mehr benutzen, auch mit PostgreSQL nicht.
Welche Alternativen hätte ich? In ein Set rein schieben und wieder raus holen? Oder diskret aussortieren?
Benutzeravatar
sparrow
User
Beiträge: 4219
Registriert: Freitag 17. April 2009, 10:28

@mechanicalStore: Es geht nur um das Argument, das man .distinct() mitgeben kann. Und da hast du ja bereits bemerkt, dass das nicht geht. Und du müsstest auch einen Fehler oder eine Warnung bekommen haben.

@__blackjack__: Das ist nur für Backends außer postgres deprecated:
https://docs.sqlalchemy.org/en/20/core/selectable.html#sqlalchemy.sql.expression.Select.distinct hat geschrieben: optional column expressions. When present, the PostgreSQL dialect will render a DISTINCT ON (<expressions>) construct. A deprecation warning and/or CompileError will be raised on other backends.
Deprecated since version 1.4: Using *expr in other dialects is deprecated and will raise CompileError in a future version.
mechanicalStore
User
Beiträge: 135
Registriert: Dienstag 29. Dezember 2009, 00:09

sparrow hat geschrieben: Sonntag 28. April 2024, 20:40 @mechanicalStore: Es geht nur um das Argument, das man .distinct() mitgeben kann. Und da hast du ja bereits bemerkt, dass das nicht geht.
Alles klar, danke.
Und du müsstest auch einen Fehler oder eine Warnung bekommen haben.
Weder, noch. Hat einfach keinerlei Wirkung gezeigt.
Antworten