2013-06-06 7 views
5

Ich versuche, eine Select-Abfrage mithilfe von sqlalchemy zu erstellen, aber ich muss die Ergebnisse nach einem berechneten Wert sortieren, und ich bin mir nicht sicher, wie es geht.Sqlalchemy Reihenfolge von errechneten Spalte

Grundsätzlich habe ich eine ‚START_TIME‘ und ‚end_time‘ Spalten und ich möchte die Ergebnisse auf START_TIME Basis bestellen und dann end_time aber wenn end_time < START_TIME Ich möchte 86400000, um es hinzuzufügen:

end_time + (86400000 if end_time < start_time else 0) 

Ich kann nicht herausfinden, wie es geht. Gibt es eine einfache Möglichkeit, meiner Tabellenklasse eine berechnete Eigenschaft hinzuzufügen und die Abfrage diese Eigenschaft abrufen zu lassen?

Ich habe versucht, mit @property einen Getter für diese berechnete end_time zu erstellen, aber es hat nicht funktioniert.

Antwort

6

Zuerst müssen Sie Spalte definieren, die Ihre Formel als SQL-Funktion implementiert enthalten (s)

als Sie Ihre Abfrage mit definierten Spalte bauen:

col = tclass.end_time + case([(tclass.end_time<tclass.start_time, 86400000)], else_=0) 
q = session.query(col).order_by(col) 
print q 

Es gibt auch Art und Weise berechnete hinzuzufügen solche Spalte zur Mapped Objektklasse defintion:

class TName(Base): 
    end_time = Column(Integer) 
    start_time = Column(Integer) 
    calc_column = end_time + case([(end_time<start_time, 86400000)], else_=0) 

q2 = session.query(TName.calc_column).order_by(TName.calc_column) 
+0

Thid funktioniert, aber gibt es eine Möglichkeit, eine berechnete Eigenschaft zu meiner Tabelle hinzuzufügen, so dass die Abfrage es immer abrufen wird? Beachten Sie, dass diese Eigenschaft nicht in der DB gespeichert werden sollte. – Ofir

+0

Dies ist auch machbar mit SQLAlchemy - siehe Update auf meine Antwort – vvladymyrov

+0

So einfach und elegant! Tolle! 10x – Ofir

0

die sqlalchemy documentation scheint jetzt mit einem Hybrid zu empfehlen, dies zu tun.

Beispiel:

from sqlalchemy.ext.hybrid import hybrid_property 

class Tname(Base): 
    end_time = Column(Integer) 
    start_time = Column(Integer) 

    @hybrid_property 
    def calc_column(self): 
     if self.end_time < self.start_time: 
      return self.end_time + 86400000 
     else: 
      return self.end_time 

Dann können Sie einfach eine typische Abfrage und Bestellung von calc_column laufen.

+0

Wird die Berechnung in der Datenbank oder im Python-Anwendungscode durchgeführt? Wenn dies in Python der Fall ist, könnte das ein Mischen vieler Daten über das Netzwerk beinhalten, die vermieden werden könnten, indem die Berechnung in der Datenbank ausgeführt wird (z.B. wenn in einer WHERE-Klausel eine Kalkspalte verwendet wird). – btubbs

+0

Wenn Sie den Ausdruck für die Eigenschaft angeben, wird er zur Berechnung des Werts auf der Seite der Datenbank verwendet, andernfalls in Python. – zgoda

Verwandte Themen