繁体   English   中英

SQLAlchemy association_proxy如何双向使用?

[英]How can SQLAlchemy association_proxy be used bi-directionally?

我正在与Flask-SQLAlchemy一起使用Association Objectsassociation_proxy创建多对多关系,但是我遇到了一个问题:当我使用association_proxy ,可以对其进行设置,以便在追加新实例时进行设置到关系的一侧,将创建关联对象,但是如果我尝试从关系的另一侧添加实例,则不会将关联对象的构造函数传递给正确的实例。

这是一个简化的示例,其中Club有很多People ,而People有很多Club ,并且关联对象是Membership

class Club(db.Model):
    __tablename__ = 'clubs'

    id = db.Column(db.Integer, db.Sequence('clubs_id_seq'), autoincrement=True, primary_key=True)
    name = db.Column(db.String(255))
    memberships = db.relationship('Membership', backref='club')
    members = association_proxy('memberships', 'club') # Can I pass a Person instance to Membership here? 
    created_at = db.Column('created_at', db.DateTime, default=datetime.datetime.now())

    def __init__(self, name):
        self.name = name

class Person(db.Model):
    __tablename__ = 'people'

    id = db.Column(db.Integer, db.Sequence('people_id_seq'), autoincrement=True, primary_key=True)
    name = db.Column(db.String(255))
    memberships = db.relationship('Membership', backref='person')
    clubs = association_proxy('memberships', 'club')
    created_at = db.Column('created_at', db.DateTime, default=datetime.datetime.now())

    def __init__(self, name):
        self.name = name

class Membership(db.Model):
    __tablename__ =  'memberships'

    person_id = db.Column('person_id', db.Integer, db.ForeignKey('people.id'), primary_key=True)
    club_id = db.Column('club_id', db.Integer, db.ForeignKey('clubs.id'), primary_key=True)
    club = db.relationship('Club', backref='membership')
    joined_at = db.Column('joined_at', db.DateTime, default=datetime.datetime.now())

    def __init__(self, club):
        self.club = club

我使用的是association_proxy因为不仅仅ClubPerson之间的连接很重要; 如果需要,我还希望能够检索Membershipjoined_at属性。 在大多数情况下,虽然,我只将查询并追加到.members一的Club.clubs一个的Person 在此示例中,我可以通过调用person_instance.clubs.append(club_instance)创建一个新的Membership ,但是由于Membership的构造函数只能接受一个参数,因此如果我想如何调用club_instance.members.append(person_instance)向后工作? 我可能会遍历club_instance.members似乎很club_instance.members ,但必须记住不要append() 我想念什么吗?

此Google网上论坛讨论中找到了我的答案。 这是相关的部分:

class DossierTarife(Base):
    __tablename__ = 'tarifer_dossier'
    IdDossier = Column(Integer, ForeignKey('dossier.IdDossier'), primary_key=True)
    IdAt = Column(Integer, ForeignKey('article_tarife.IdAt'), primary_key=True)

    dossier = relationship(Dossier, backref=backref("tarifer_dossier", cascade="all, delete-orphan"))
    article_tarife = relationship(ArticleTarife, backref=backref("tarifer_dossier"))

class Dossier(Base):
    __tablename__ = 'dossier'
    IdDossier = Column('IdDossier', Integer, primary_key=True)
   ...

class ArticleTarife(Base):
    __tablename__ = 'article_tarife'
    IdAt = Column('IdAt', Integer, primary_key=True)
   ...

Dossier.LesTar = association_proxy("tarifer_dossier", "article_tarife", creator=lambda art:DossierTarife(article_tarife=art))
ArticleTarife.LesTar = association_proxy("tarifer_dossier", "dossier", creator=lambda dos:DossierTarife(dossier=dos))

我直接在类定义中分配了association_proxy而不是按照上述事实进行分配,而且效果也很好。

这样的SO回答也非常有帮助, 描述了如何正确删除关联对象行:

user = relationship(User, backref=backref('user_to_groups', cascade='all, delete-orphan'))
group = relationship(Group, backref=backref('group_to_user', cascade='all, delete-orphan'))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM