SQLAlchemyで多対多マッピングのようなソーシャルネットワークを作成しようとしています。つまり、CharacterクラスとCharacter_relationsクロステーブルを使用してCharacterからCharacterにリンクします。今までこれは簡単です:SQLAlchemy:あなたが私と一緒にいるなら、私はあなたと一緒にいます - 自己参照のM2M関係
character_relationships = Table('character_relationships', Base.metadata,
Column('me_id', Integer, ForeignKey('characters.id', ondelete=True, onupdate=True), nullable=False, primary_key=True),
Column('other_id', Integer, ForeignKey('characters.id', ondelete=True, onupdate=True), nullable=False, primary_key=True),
UniqueConstraint('me_id', 'other_id', name='uix_1')
)
class CharacterRelationship(object):
def __init__(self, me_id, other_id):
self.me_id = me_id
self.other_id = other_id
mapper(CharacterRelationship, character_relationships)
class Character(IdMixin, TimestampMixin, Base):
__tablename__ = "characters"
name = Column(Unicode, nullable=False)
friends = relationship(lambda: Character, secondary=character_relationships,
primaryjoin=lambda: Character.id==character_relationships.c.me_id,
secondaryjoin=lambda: Character.id==character_relationships.c.other_id,
backref=backref('knows_me')
)
2つの可能な関係があります:片側および両側です。それは私が持つことができるクロステーブルにあります
CharacterRelationship(me_id=1, other_id=2)
CharacterRelationship(me_id=2, other_id=1)
上記のCharacter.friends引数は、単方向関係に関するものです。二国間関係のためにどのようにプロパティ/ column_propertyを追加できますか?
my_character.real_friendsには、「両側から立っている」関係の場合、CharacterRelationshipのエントリのみが含まれています。
私は
@property
def real_friends(self):
return set(my_character.friends) & set(my_character.knows_me)
のようなものを使用することができますが、これは、SQLによく翻訳していない、と私はデータベースレベルでこのセットの交差点をやって巨大な高速化を期待することを知っています。しかし、さらに達成することがあります!
さらに良いことには次のように最終的なオブジェクト持っているだろう:
character.friends.other_character
character.friends.relationship_type = -1 | 0 | 1
- を-1私が一方的に他のを知っている意味、
- 0二国間、
- 1は、他が知っていること私は一方的に
このロジックをデータベースレベルに設定する理由はありますか。はいの場合、どうしますか? もしあなたが知っていれば、単純なreal_friendのバイラテラル部分をデータベースレベルに置く方法を知っていますか?
は 'object_session(自己を使用することを忘れないでください) ' – Eric