2009-12-18 2 views
2

테이블 x과 테이블 y 사이에 일대 다 관계가있는 SQLAlchemy 모델이 있습니다. 테이블 y에있는 id이 가장 큰 레코드 (있는 경우)는 y.x_id = x.id이 특별합니다. 클래스 X 및 클래스 Y지도 테이블 xy.컬렉션의 최신 개체를 나타내는 SQLAlchemy 관계는 어떻게 정의합니까?

X.all_y (ORDER BY y.id)을 정의하는 방법을 알고 있습니다. X.latest_yX.all_y[-1]과 어떻게 동일하게 정의합니까?

답변

4

순전히 관계형을 사용하려면 하위 쿼리를 사용하여 상위 항목과 상관 된 "최신"또는 "최대"값을 가져와 컬렉션 멤버와 동일시해야합니다. 일부 플랫폼은 LIMIT를 사용하는 당신이 집계를 피할 수 있기 때문에 당신이 빠른 결과를 생성 할 수 있습니다 할 수있는, 또는

from sqlalchemy import * 
from sqlalchemy.orm import * 

engine = create_engine('sqlite:///:memory:', echo='debug') 

m = MetaData() 

parent = Table('parent', m, 
       Column('id', Integer, primary_key=True) 
) 

child = Table('child', m, 
       Column('id', Integer, primary_key=True), 
       Column('parent_id', Integer, ForeignKey('parent.id')), 
       Column('sortkey', Integer) 
       ) 

m.create_all(engine) 

class Parent(object): 
    def __init__(self, children): 
     self.all_c = children 

class Child(object): 
    def __init__(self, sortkey): 
     self.sortkey = sortkey 

latest_c = select([func.max(child.c.sortkey)]).\ 
       where(child.c.parent_id==parent.c.id).\ 
       correlate(parent).\ 
       as_scalar() 

mapper(Parent, parent, properties={ 
    'all_c':relation(Child), 
    'latest_c':relation(Child, 
          primaryjoin=and_(
           child.c.sortkey==latest_c, 
           child.c.parent_id==parent.c.id 
          ), 
          uselist=False 
    ) 
}) 

mapper(Child, child) 

session = sessionmaker(engine)() 

p1, p2, p3 = Parent([Child('a'), Child('b'), Child('c')]), \ 
       Parent([Child('b'), Child('c')]),\ 
       Parent([Child('f'), Child('g'), Child('c')]) 

session.add_all([p1, p2, p3]) 
session.commit() 

assert p1.latest_c.sortkey == 'c' 
assert p2.latest_c.sortkey == 'c' 
assert p3.latest_c.sortkey == 'g' 

: 그것은 당신이 "최신"을 결정하는 컬럼에 인덱스를 넣을 경우 최상의 결과를 얻을 수 있습니다 의미 그 기본 키 컬렉션 항목에 가입 할 수 있습니다 :

latest_c = select([child.c.id]).\ 
       where(child.c.parent_id==parent.c.id).\ 
       order_by(child.c.sortkey.desc()).\ 
       limit(1).\ 
       correlate(parent).\ 
       as_scalar() 

mapper(Parent, parent, properties={ 
    'all_c':relation(Child), 
    'latest_c':relation(Child, 
          primaryjoin=and_(
           child.c.id==latest_c, 
           child.c.parent_id==parent.c.id 
          ), 
          uselist=False 
    ) 
}) 
+0

감사합니다, 내가 없어진 .correlate()를 – joeforker

+0

는 ORM 모델을 사용하여 같은 일을 할 수 있습니까? –

관련 문제