2014-09-13 2 views
3

나는이 SQL 쿼리를 가지고 : 내가 ORM 쿼리 형태로 쓸 수 있습니다 알고groupby를 사용하는 column_properties를 만들려면 어떻게해야합니까?

select 
    rooms.*, 
    COUNT(DISTINCT(o.resident_id)) as resident_count, 
    COUNT(reviews.id) as review_count, 
    COUNT(photos.id) as photo_count, 
    AVG(reviews.rating) as mean_review 
from 
    t_rooms rooms 
JOIN 
    t_room_listings listings on listings.room_id = rooms.id 
JOIN 
    t_occupancies o on o.listing_id = listings.id 
LEFT JOIN 
    t_reviews reviews on reviews.occupancy_id = o.id 
LEFT JOIN 
    t_photos photos on photos.occupancy_id = o.id 
GROUP BY rooms.id 

등 :

q = (session 
    .query(
     Room, 
     func.count(func.distinct(Occupancy.resident_id)).label('resident_count'), 
     func.count(Review.id).label('review_count'), 
     func.count(Photo.id).label('photo_count'), 
     (
      (3 + func.avg(Review.rating))/(1 + func.count(Review.rating)) 
     ).label('bayesian_rating') 
    ) 
    .select_from(
     join(Room, RoomListing).join(Occupancy).outerjoin(Review).outerjoin(Photo) 
    ) 
    .group_by(Room.id) 
) 

for room, res_ct, rev_ct, p_ct in q: 
    wish_that_I_could_write(room.res_ct, room.rev_ct, room.p_ct, room.score) 

하지만 내 Room 클래스 resident_count, review_countcolumn_property 등의 선언 할 수있는 방법 , 그래서 매번이 쿼리를 만들 필요가 없습니까?

답변

1

당신은 너무 같은 개체에 매핑 쿼리이 결과를 얻을 수 있습니다 column_property

class ExtendedRoom(object): 
    pass 


# q is your query 
mapper(ExtendedRoom, q.statement.alias()) 
for room in session.query(ExtendedRoom).all(): 
    # now room have review_count and other attributes 
    print(room.review_count) 

여기에 간단한 예를.

from sqlalchemy import create_engine, Column, Integer, MetaData, Table, String, func 
from sqlalchemy.sql import select 
from sqlalchemy.orm import sessionmaker, mapper, column_property 
from sqlalchemy.ext.declarative import declarative_base 


engine = create_engine('sqlite:///:memory:', echo=True) 
Session = sessionmaker(bind=engine) 
Base = declarative_base() 
session = Session() 
metadata = MetaData() 


room = Table('room', metadata, 
    Column('id', Integer, primary_key=True), 
    Column('name', String), 
    Column('num', Integer, default=0), 
) 
metadata.create_all(engine) 
statement = select([room]).group_by(room.c.id).alias() 


class Room(object): 
    pass 


mapper(Room, statement, properties={ 
    'count': column_property(func.count(statement.c.num)), 
}) 


print(session.query(Room).all()) 
관련 문제