2010-06-06 16 views
3

Je suis en train de convertir cela en quelque chose sqlalchemy expression langue compatible, je ne sais pas si c'est possible hors de la boîte et espèrent quelqu'un de plus expérimenté peut m'aider. Le back-end est PostgreSQL et si je ne peux pas faire comme une expression que je vais créer une chaîne à la place ::SQLAlchemy Expression Langue problème

SELECT 
    DISTINCT date_trunc('month', x.x) as date, 
    COALESCE(b.res1, 0) AS res1, 
    COALESCE(b.res2, 0) AS res2 
FROM 
    generate_series(
     date_trunc('year', now() - interval '1 years'), 
     date_trunc('year', now() + interval '1 years'), 
     interval '1 months' 
    ) AS x 
LEFT OUTER JOIN(
    SELECT 
     date_trunc('month', access_datetime) AS when, 
     count(NULLIF(resource_id != 1, TRUE)) AS res1, 
     count(NULLIF(resource_id != 2, TRUE)) AS res2 
    FROM tracking_entries 
    GROUP BY 
     date_trunc('month', access_datetime) 
    ) AS b 
ON (date_trunc('month', x.x) = b.when) 

D'abord je me suis un TrackingEntry de classe mappée à tracking_entries, l'instruction select dans les l'extérieur peut être converti rejoint à quelque chose comme (pseudocode) ::

from sqlalchemy.sql import func, select 
from datetime import datetime, timedelta 

stmt = select([ 
    func.date_trunc('month', TrackingEntry.resource_id).label('when'), 
    func.count(func.nullif(TrackingEntry.resource_id != 1, True)).label('res1'), 
    func.count(func.nullif(TrackingEntry.resource_id != 2, True)).label('res2') 
    ], 
    group_by=[func.date_trunc('month', TrackingEntry.access_datetime), ]) 

compte tenu de l'instruction select externe Je ne sais pas comment construire, je suppose quelque chose comme ::

outer = select([ 
     func.distinct(func.date_trunc('month', ?)).label('date'), 
     func.coalesce(?.res1, 0).label('res1'), 
     func.coalesce(?.res2, 0).label('res2') 
    ], 
    from_obj=[ 
     func.generate_series(
       datetime.now(), 
       datetime.now() + timedelta(days=365), 
       timedelta(days=1) 
      ).label(x) 
    ]) 

Je suppose que je dois relier ces déclarations ensemble sans utiliser clés étrangères ::

outer.outerjoin(stmt???).??(func.date_trunc('month', ?.?), ?.when) 

Quelqu'un at-il des suggestions ou encore mieux une solution?

http://pastie.org/994367

Répondre

1

pas une réponse complète mais quand vous voulez rejoindre select() objets ensemble, ils ont un « .c. » attribut, ils gagnent effectivement la même interface que la table elle-même. si

s1 = select(...) 
s2 = select(...) 

s3 = select([s1,s2]).select_from(s1.join(s2, s1.c.foo==s2.c.bar)) 

de même pour les fonctions

select ([func.foo(s1.c.x)]).select_from(s1.join(s2, ...)) 
+0

Merci, je l'ai résolu maintenant. L'exécution de postmaster en mode débogage rendait beaucoup plus facile de voir à quoi ressemblaient réellement les requêtes résultantes, m'a aidé à comprendre où les problèmes se posaient. J'ai aussi dû utiliser .alias (somename) sur l'une des sélections, postgresql n'a pas aimé le nommage anonyme. – Torkel