Wie verwende ich Unterabfragen in SQLAlchemy, um einen gleitenden Durchschnitt zu erhalten?

Mein Problem ist, dass ich sowohl eine Liste von Messungen als auch einen gleitenden Durchschnitt dieser Messungen abrufen möchte. Ich kann das mit dieser SQL-Anweisung (postgresql interval syntax) machen:

SELECT time, value,                
   (
       SELECT AVG(t2.value)
       FROM measurements t2
       WHERE t2.time BETWEEN t1.time - interval '5 days' AND t1.time
   ) moving_average
FROM measurements t1
ORDER BY t1.time;

Ich möchte den SQLAlchemy-Code haben, um eine ähnliche Anweisung zu erzeugen. Ich habe derzeit diesen Python-Code:

moving_average_days = # configureable value, defaulting to 5
t1 = Measurements.alias('t1')
t2 = Measurements.alias('t2')
query = select([t1.c.time, t1.c.value, select([func.avg(t2.c.value)], t2.c.time.between(t1.c.time - datetime.timedelta(moving_average_days), t1.c.time))],
            t1.c.time > (datetime.datetime.utcnow() - datetime.timedelta(ndays))). \
        order_by(Measurements.c.time)

Das generiert jedoch diese SQL:

SELECT t1.time, t1.value, avg_1
FROM measurements AS t1,
    (
        SELECT avg(t2.value) AS avg_1
        FROM measurements AS t2
        WHERE t2.time BETWEEN t1.time - %(time_1)s AND t1.time
    )
WHERE t1.time > %(time_2)s
ORDER BY t1.time;

Dieses SQL hat die Unterabfrage als Teil der FROM-Klausel, wo es keinen skalaren Zugriff auf die Spaltenwerte der Werte der obersten Ebene haben kann, d. H. PostgreSQL spuckt diesen Fehler aus:

ERROR:  subquery in FROM cannot refer to other relations of same query level
LINE 6:         WHERE t2.time BETWEEN t1.time - interval '5 days' AN...

Was ich also wissen möchte ist: Wie kann ich SQLAlchemy veranlassen, die Unterabfrage in die SELECT-Klausel zu verschieben?

Alternativ wäre eine andere Möglichkeit, einen gleitenden Durchschnitt zu erhalten (ohne eine Abfrage für jedes (Zeit-, Wert-) Paar durchzuführen), eine Option.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage