2009-12-11 2 views
10

내 응용 프로그램에 트위터의 "팔로어"기능을 모방 한 SQLAlchemy 모델이 설정되어 있습니다. 사용자는 서로에게 다자간 관계 (추종자와 추종자 모두)가 있습니다. 보조 테이블이 다시 의미하기 때문에SQLAlchemy 단일 테이블의 다 대다 관계

t_users = sa.Table("users", meta.metadata, 
    sa.Column("id", sa.types.Integer, primary_key=True), 
    sa.Column("email", sa.types.String(320), unique=True, nullable=False), 
    ...etc... 
    ) 

t_follows = sa.Table("follows", meta.metadata, 
    sa.Column("id", sa.types.Integer, primary_key=True), 
    sa.Column("follower_id", sa.types.Integer, sa.ForeignKey('users.id'), nullable=False), 
    sa.Column("followee_id", sa.types.Integer, sa.ForeignKey('users.id'), nullable=False) 
    ) 

나는이 관계를 만들 orm.mapper 사용하려고 시도하는, 그러나 장애물의 비트에 실행했습니다 : 표는 다음과 같이 구성되어 있습니다 (SA는 SQLAlchemy의 모듈입니다) 동일한 기본 테이블에 두 방향으로. 이 관계를 ORM에 매핑하는 방법은 무엇입니까?

답변

6

당신은이 경우에 명시 적으로 primaryjoinsecondaryjoin 조건을 작성해야합니다 :

mapper(
    User, t_users, 
    properties={ 
     'followers': relation(
      User, 
      secondary=t_follows, 
      primaryjoin=(t_follows.c.followee_id==t_users.c.id), 
      secondaryjoin=(t_follows.c.follower_id==t_users.c.id), 
     ), 
     'followees': relation(
      User, 
      secondary=t_follows, 
      primaryjoin=(t_follows.c.follower_id==t_users.c.id), 
      secondaryjoin=(t_follows.c.followee_id==t_users.c.id), 
     ), 
    }, 
) 

난 당신이 primaryjoinsecondaryjoin 매개 변수의 의미를 더 잘 이해할 수 있도록 자세한이 샘플을 작성했습니다. 물론 backref으로 분류기를 만들 수 있습니다.

현재, 다음 표에 id 열이 필요하지 않습니다. 복합 기본 키를 대신 사용하십시오. 실제로 고유 한 제약 조건은 follower_idfollowee_id 쌍으로 (기본 또는 추가 고유 키로) 정의해야합니다.

+0

감사합니다. 다음 테이블에 ID 열이 필요없고 복합 PK를 사용할 수 있다는 것을 의미합니까? 나는 이것이 users 테이블에서 어떻게 작동 하는지를 보지 못했다. – Travis

+0

예, 실수였습니다. 나는 다음 표를 의미했다. –

+0

나는 이것에 부딪쳤고 선언적으로해야만했다. 미래의 파인더에 상응하는 것이 여기있다. –

14

선언적으로 수행 할 수도 있습니다.

위의 코드를 기반으로 비슷한 예제가 있습니다. backref를 사용합니다.

+0

나를 위해 의 foreign_keys = [VolumeRelationship.c.VolumeID, VolumeRelationship.c.ParentID])의 아날로그를'Volume.parents'에 추가해야했습니다. 그렇지 않으면'NoReferencedTableError'를 가졌습니다. –