2013-06-06 13 views
5

Próbuję utworzyć kwerendę wyboru za pomocą sqlalchemy, ale muszę posortować wyniki według obliczonej wartości i nie jestem pewien, jak to zrobić.Porządek uporządkowania według kolumny obliczeniowej

Zasadniczo mam 'START_TIME' i kolumny 'end_time' i chcę zamówić wyniki w oparciu o START_TIME a następnie end_time ale jeśli end_time < start_time chcę dodać 86400000 do niego:

end_time + (86400000 if end_time < start_time else 0) 

Nie mogę wymyślić, jak to zrobić. Czy istnieje prosty sposób dodania obliczonej właściwości do mojej klasy tabeli i czy zapytanie odczytuje tę właściwość?

Próbowałem już użyć @property do utworzenia gettera dla tego obliczonego czasu końcowego, ale nie zadziałało.

Odpowiedz

6

Najpierw trzeba zdefiniować kolumnę, która będzie zawierać formuła zaimplementowane jako funkcja (y) SQL

niż budować zapytanie za pomocą zdefiniowanego kolumna:

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

Jest też sposobem na dodanie takich obliczeniowy kolumna do odwzorowane klasy Object umowach definicja:

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 działa, ale czy istnieje sposób na dodanie obliczonej właściwości do mojej tabeli, aby zapytanie zawsze ją odbierało? Zauważ, że ta właściwość nie powinna być przechowywana w DB. – Ofir

+0

Jest to również możliwe dzięki SQLAlchemy - patrz aktualizacja do mojej odpowiedzi – vvladymyrov

+0

Tak prosta i elegancka! Niesamowity! 10x – Ofir

0

sqlalchemy documentation teraz wydaje zalecamy używania hybrydę to zrobić.

Przykład:

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 

Następnie można po prostu uruchomić typowy zapytania i zamówienia przez calc_column.

+0

Czy obliczenia będą wykonywane w bazie danych, czy w kodzie aplikacji Python? Jeśli w Pythonie, może to oznaczać tasowanie wielu danych w sieci, których można uniknąć, wykonując obliczenia wewnątrz DB (np. Przy użyciu kolumny calc w klauzuli WHERE). – btubbs

+0

Jeśli określisz wyrażenie dla właściwości, będzie ono używane do obliczania wartości po stronie db, w Pythonie w przeciwnym razie. – zgoda

Powiązane problemy