views:

157

answers:

1

I want to generate this query in sqlalchemy. The table 'demande' exists in the database. There is a subquery that generates the timesteps with the generate_series function.

SELECT
    timesteps.timestep AS timestep, d.count AS count
FROM
    (SELECT
        DATE_TRUNC('hour',date_demande) AS timestep,
        COUNT(id) AS count
     FROM
        demande
     GROUP BY
        timestep
    ) AS d

RIGHT OUTER JOIN
    (SELECT
        timestep
     FROM
        generate_series('2010-01-01 00:00:00'::timestamp,
                        '2010-01-01 23:59:59'::timestamp,
                        '1 hour'::interval) AS timestep
     ) AS timesteps
  ON d.timestep = timesteps.timestep

ORDER BY timestep;

I've tried this :

stmt = session.query(
        func.
            generate_series(
                datetime.datetime(2010,1,1,0,0,0),
                datetime.datetime(2010,1,1,23,59,59),
                cast('1 hour',Interval())).
            label('timestep')
        ).subquery()
print stmt
q = session.query(
        stmt.c.timestep,
        func.count(Demande.id)).
    outerjoin((Demande, grouped==stmt.c.timestep)).
    group_by(stmt.c.timestep)
print q

But it complains with an InvalidRequesError: Could not find a FROM clause to join from. I guess this is caused by the subquery.

If i try to "invert" the query, it works but it does a 'LEFT OUTER JOIN' :

q = session.query(
        func.count(Demande.id),
        stmt.c.timestep).
    outerjoin((stmt, grouped==stmt.c.timestep)).
    group_by(stmt.c.timestep)

As there is no RIGHT OUTER JOIN in sqlalchemy, I just want to find a way to take the subquery as the first table and the 'demande' table as the second one. This way I will be able to use LEFT OUTER JOIN

+1  A: 

The following example should give you a clue (assuming I correctly guessed that Demande is declarative model):

joined = stmt.outerjoin(Demande.__table__, Demande.grouped==stmt.c.timestep)
q = session.query(stmt.c.timestep, func.count(Demande.id)).\
        select_from(joined).\
        group_by(stmt.c.timestep)
Denis Otkidach
I have to try this tomorrow at work, thanks for your answer, it seems nice
Ghislain Leveque
OK, you've learned me something but I still need to work on it to achieve what I'm looking for. Thanks anyway
Ghislain Leveque