2013-08-14 15 views
6

ho bisogno di un piccolo aiuto. Ho una query successiva e sono curiosa su come rappresentarla in termini di sqlalchemy.orm. Attualmente lo sto eseguendo tramite session.execute. Non è fondamentale per me, ma sono solo curioso. La cosa che in realtà non so è come mettere sottoquery nella clausola FROM (vista nidificata) senza fare alcun join.SQLAlchemy sottoquery in da clausola senza join

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 

ho bisogno di questa cosa sottoquery a causa del problema di velocità - senza limiti nella funzione di query più interna regexp_split_to_table inizia ad analizzare tutti i dati e limita solo dopo che. Ma il mio tavolo è enorme e non posso permettermelo.

Se qualcosa non è molto chiaro, per favore, chiedi, io farò del mio meglio)

risposta

8

Presumo che questo è PostgreSQL.

Per creare una sottoquery, utilizzare il metodo subquery(). L'oggetto risultante può essere utilizzato come se fosse l'oggetto Table. Ecco come la vostra richiesta sarà simile a SQLAlchemy:

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) 

Tuttavia, si potrebbe evitare una sottoquery utilizzando unnest funzione invece di convertire array stringa con arrayt_to_string e poi dividere con 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) 
Problemi correlati