2012-02-28 12 views
8
class Employee 
    id 
    name 

class Location 
    id 
    city 

class Work 
    id 
    employee_id 
    location_id 

Todo: Izquierda unirse con el recuento (incluyendo el cero)sqlalchemy combinación izquierda con el recuento de

resultado deseado

location.city count 
    NYC 10 
    SFO 5 
    CHI 0 

Raw Consulta:

select location.id, count(work.id) as count 
    from location 
    left join work 
    on location.id = work.location_id 
    group by location.id 

sqlalchemy:

db_session.query(Location, func.count.work_id).label('count')). \ 
       filter(location.id == work.location_id). \ 
       group_by(location._id). \ 

¿Cuál es la forma correcta de especificar columnas en seleccionar mientras se hace una combinación izquierda?

Respuesta

7

Defina una relación entre sus tablas cuando defina el modelo de orm. Ver this tutorial. En su ejemplo, Work es una tabla de asociación, por lo que si usted no tiene ningún otro dato en Work, se puede utilizar un many to many relationship por ejemplo:

from sqlalchemy.orm import relationship 

class Work 
    id 
    employee_id 
    location_id 

class Employee 
    id 
    name 

class Location 
    id 
    city 
    employees = relationship(Employee, secondary=Work, backref='locations') 

Entonces consulta:

session.query(Location, func.count(Work.id)).outerjoin(Work).group_by(Location) 

Como usted tiene definió la relación, sqlalchemy sabrá la dirección y las columnas para outerjoin.

Al hacer el group_by, es importante pasar Location y no sólo Location.id, porque al hacerlo select(Location), sqlalchemy seleccionará todas las columnas en la ubicación, y por lo que también debe pasar todas las columnas de la ubicación.

Cuestiones relacionadas