2013-08-14 15 views
6

ich ein wenig Hilfe brauchen. Ich habe folgende Abfrage und ich bin, gespannt, wie es von sqlalchemy.orm in Bezug zu vertreten. Momentan führe ich es mit session.execute aus. Es ist nicht kritisch für mich, aber ich bin nur neugierig. Die Sache, die ich bin eigentlich nicht wissen, ist, wie Unterabfrage in FROM-Klausel (verschachtelte Ansicht) zu setzen, ohne dabei irgendwelche beizutreten.SQLAlchemy Unterabfrage in von Klausel ohne beitreten

select g_o.group_ from (
    select distinct regexp_split_to_table(g.group_name, E',') group_ 
     from (
      select array_to_string(groups, ',') group_name 
      from company 
      where status='active' 
      and array_to_string(groups, ',') like :term 
      limit :limit 
     ) g 
    ) g_o 
where g_o.group_ like :term 
order by 1 
limit :limit 

Ich brauche diese Unterabfrage Sache, weil der Geschwindigkeit Problem - ohne Begrenzung in der innersten Abfragefunktion regexp_split_to_table beginnt um alle Daten zu analysieren und schränkt erst danach. Aber mein Tisch ist riesig und ich kann mir das nicht leisten.

Wenn etwas nicht ganz klar ist, bitte, fragen, ich werde mein Bestes tun)

Antwort

8

Ich nehme an, dies PostgreSQL ist.

eine Unterabfrage zu erstellen, verwenden subquery() Methode. Das resultierende Objekt kann verwendet werden, als ob es Table Objekt war. Hier ist, wie Sie Ihre Abfrage wie in SQLAlchemy aussehen:

subq1 = session.query(
    func.array_to_string(Company.groups, ',').label('group_name') 
).filter(
    (Company.status == 'active') & 
    (func.array_to_string(Company.groups, ',').like(term)) 
).limit(limit).subquery() 

subq2 = session.query(
    func.regexp_split_to_table(subq1.c.group_name, ',') 
     .distinct() 
     .label('group') 
).subquery() 

q = session.query(subq2.c.group).\ 
    filter(subq2.c.group.like(term)).\ 
    order_by(subq2.c.group).\ 
    limit(limit) 

Sie können jedoch eine Unterabfrage vermeiden, indem Sie unnest Funktion anstelle der Umwandlung Array String mit arrayt_to_string und dann spalten sie mit regexp_split_to_table:

subq = session.query(
    func.unnest(Company.groups).label('group') 
).filter(
    (Company.status == 'active') & 
    (func.array_to_string(Company.groups, ',').like(term)) 
).limit(limit).subquery() 

q = session.query(subq.c.group.distinct()).\ 
    filter(subq.c.group.like(term)).\ 
    order_by(subq.c.group).\ 
    limit(limit) 
Verwandte Themen