Проблема языка выражений SQLAlchemy - PullRequest
3 голосов
/ 07 июня 2010

Я пытаюсь преобразовать это в выражение sqlalchemy совместим с языком, я не знаю, возможно ли это из коробки и надеемся, что кто-то более опытный может помочь мне в этом. Бэкэнд это PostgreSQL, и если я не могу сделать это как выражение, я создам вместо строки ::

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)

Прежде всего, я получил класс TrackingEntry, сопоставленный с tracking_entries, оператор select во внешнем соединении может быть преобразован во что-то лайк (псевдокод) ::

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), ])

Учитывая внешний оператор выбора, я не знаю, как его построить, я думаю, что-то вроде ::

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)
    ])

Тогда я полагаю, что мне нужно связать эти утверждения вместе, не используя внешние ключи ::

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

Кто-нибудь получил какие-либо предложения или даже лучше решение?

http://pastie.org/994367

1 Ответ

1 голос
/ 07 июня 2010

не полный ответ, но когда вы хотите объединить объекты select () вместе, они имеют ".c." атрибут, они эффективно получают тот же интерфейс, что и сама таблица. так

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

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

То же самое относится к функциям

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