2013-08-27 9 views
13

Ich habe die follwing SQL-Abfrage (Es ist die größte einer bestimmten Spalte pro Gruppe erhalten ist, mit 3 Aktivitäten Gruppe von):auf eine Unterabfrage in SQLAlchemy Joining

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 

Und ich versuche, es zu konvertieren zu SQLAlchemy. Das habe ich bisher:

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

Das Problem entsteht, wenn ich den Join auf der Unterabfrage mache. Ich erhalte einen Fehler, der besagt, dass es keine from-Klausel gibt, von der aus eine Verbindung hergestellt werden kann. Das ist seltsam, weil ich einen direkt nach der Unterabfrage in der Join-Funktion als Argument angabe gebe. Irgendeine Idee, was ich falsch mache? Vielleicht muss ich etwas alias machen und wieder eine select_from machen?

EDIT: Genaue Fehler

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'. 

Es beizutreten versucht, aber es sagt, es ist nicht weiß, wo die Verbindung zu machen. Stimmt etwas nicht mit meiner Syntax? Ich denke, es ist korrekt, basierend auf der Join-Funktion.

+0

Versuchen Sie, die Unterabfrage umzubenennen, und versuchen Sie auch, mit Literal-Join-Bedingungen zu arbeiten. Sie müssen hier vielleicht etwas aushalten. – javex

+0

Wie kann ich wörtliche Join-Bedingungen verwenden? Was meinst du damit. Ich habe auch meinen Beitrag mit dem spezifischen Fehler aktualisiert. – miscsubbin

Antwort

11

Offenbar müssen Sie eine and_() um mehrere Join-Bedingungen hinzufügen.

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