在我使用flask-sqlalchemy的烧瓶应用程序中,我需要在两个联系人之间创建关联
这是我的Contact
模型
class Contact(db.Model):
__tablename__ = 'contact'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(120), nullable=False, unique=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
to_contacts = db.relationship('Contact',
secondary='ContactRelation',
primaryjoin='id==contactrelation.c.from_contact_id',
secondaryjoin='id==contactrelation.c.to_contact_id',
backref='from_contacts')
和我的关联班ContactRelation
:
class ContactRelation(db.Model):
__tablename__ = 'contactrelation'
id = db.Column(db.Integer, primary_key=True)
from_contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'))
to_contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'))
relation_type = db.Column(db.String(100), nullable=True)
我有错误:
AttributeError: type object 'ContactRelation' has no attribute 'c'
答案 0 :(得分:4)
感谢Michel和Simon SQLAlchemy mailing list我需要association_proxy和两个与Contact关系的关系。
class Contact(db.Model):
__tablename__ = 'contact'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(120), nullable=False, unique=False)
created_on = db.Column(db.DateTime, default=datetime.utcnow)
birthday = db.Column(db.DateTime)
background = db.Column(db.Text)
photo = db.Column(db.Unicode(120))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
to_contacts = association_proxy('to_relations', 'to_contact')
from_contacts = association_proxy('from_relations', 'from_contact')
class ContactRelation(db.Model):
__tablename__ = 'contactrelation'
id = db.Column(db.Integer, primary_key=True)
from_contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'))
to_contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'))
relation_type = db.Column(db.String(100), nullable=True)
from_contact = db.relationship(Contact,
primaryjoin=(from_contact_id == Contact.id),
backref='to_relations')
to_contact = db.relationship(Contact,
primaryjoin=(to_contact_id == Contact.id),
backref='from_relations')
答案 1 :(得分:1)
您的关系设计不正确。辅助应该是普通表,而不是映射类。如果您想在ContactRelation上使用额外数据(relation_type),则应使用SQLAlchemy Relationship文档中描述的关联表模式:http://docs.sqlalchemy.org/en/rel_1_1/orm/basic_relationships.html#association-object
答案 2 :(得分:1)
与关联对象的自指多对多关系。
用户类别:
class User(Base):
__tablename__ = "User"
id = Column(String(36), primary_key=True, default=lambda : str(uuid1()))
关联类别:
class UserIgnore(Base):
__tablename__ = "UserIgnore"
id = Column(String(36), primary_key=True, default=lambda : str(uuid1()))
ignored_by_id = Column("ignored_by_id", String(36), ForeignKey("User.id"), primary_key=True)
ignored_by = relationship("User", backref="ignored_list", primaryjoin=(User.id == ignored_by_id))
ignored_id = Column("ignored_id", String(36), ForeignKey("User.id"), primary_key=True)
ignored = relationship("User", backref="ignored_by_list", primaryjoin=(User.id == ignored_id))
访问关系对象
someUser.ignored_list
或
someUser.ignored_by_list
感谢Sean
答案 3 :(得分:0)
似乎如果你将to_contacts更改为如下所示,你的问题将会解决:
to_contacts = db.relationship('Contact',
secondary='ContactRelation',
primaryjoin='id==contactrelation.from_contact_id',
secondaryjoin='id==contactrelation.to_contact_id',
backref='from_contacts')