2013-08-27 13 views
13

Ho la query SQL follwing (Ottenere il più grande di una determinata colonna per gruppo, con 3 cose da gruppo di):Partecipare su una subquery in SQLAlchemy

select p1.Name, p1.nvr, p1.Arch, d1.repo, p1.Date 
from Packages as p1 inner join 
    Distribution as d1 
    on p1.rpm_id = d1.rpm_id inner join (
     select Name, Arch, repo, max(Date) as Date 
     from Packages inner join Distribution 
      on Packages.rpm_id = Distribution.rpm_id 
     where Name like 'p%' and repo not like '%staging' 
     group by Name, Arch, repo 
    ) as sq 
    on p1.Name = sq.Name and p1.Arch = sq.Arch and d1.repo = sq.repo and p1.Date = sq.Date 
    order by p1.nvr 

e sto cercando di convertirlo a SQLAlchemy. Questo è quello che ho finora:

p1 = aliased(Packages) 
d1 = aliased(Distribution) 
sq = session.\ 
     query(
      Packages.Name, 
      Packages.Arch, 
      Distribution.repo, 
      func.max(Packages.Date).\ 
             label('Date')).\ 
     select_from(
      Packages).\ 
     join(
      Distribution).\ 
     filter(
      queryfilter).\ 
     filter(
      not_(Distribution.repo.\ 
            like('%staging'))).\ 
     group_by(
      Packages.Name, 
      Packages.Arch, 
      Distribution.repo).subquery() 

result = session.\ 
      query(
       p1, d1.repo).\ 
      select_from(
       p1).\ 
      join(
       d1).\ 
      join(
       sq, 
       p1.Name==sq.c.Name, 
       p1.Arch==sq.c.Arch, 
       d1.repo==sq.c.repo, 
       p1.Date==sq.c.Date).\ 
      order_by(p1.nvr).all() 

Il problema sorge quando eseguo il join nella sottoquery. Ricevo un errore che afferma che non esiste una clausola da cui entrare. Questo è strano perché ne indico uno subito dopo la subquery nella funzione join come argomento. Qualche idea su cosa sto facendo male? Forse ho bisogno di alias qualcosa e faccio di nuovo select_from?

EDIT: errore esatta

Could not find a FROM clause to join from. Tried joining to SELECT "Packages"."Name", "Packages"."Arch", "Distribution".repo, max("Packages"."Date") AS "Date" FROM "Packages" JOIN "Distribution" ON "Packages".rpm_id = "Distribution".rpm_id WHERE "Packages"."Name" LIKE :Name_1 AND "Distribution".repo NOT LIKE :repo_1 GROUP BY "Packages"."Name", "Packages"."Arch", "Distribution".repo, but got: Can't find any foreign key relationships between 'Join object on %(139953254400272 Packages)s(139953254400272) and %(139953256322768 Distribution)s(139953256322768)' and '%(139953257005520 anon)s'. 

Sta cercando di aderire, ma dice che non sa dove fare il join. C'è qualcosa di sbagliato nella mia sintassi? Penso che sia corretto sulla base di ciò che è nella funzione di join.

+0

Provare ad alias la sottoquery e anche a lavorare con condizioni di join letterali. Potrebbe essere necessario un po 'di maturità qui. – javex

+0

Come posso utilizzare condizioni letterali di join? Che cosa vuoi dire con questo. Ho anche aggiornato il mio post con l'errore specifico. – miscsubbin

risposta

11

A quanto pare è necessario aggiungere un and_() in base a più condizioni di join.

join(
    sq, 
    and_(p1.Name==sq.c.Name, 
    p1.Arch==sq.c.Arch, 
    d1.repo==sq.c.repo, 
    p1.Date==sq.c.Date)).\