In my flask application with flask-sqlalchemy i need to create association between two contact
here is my Contact
model
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')
and my association class 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)
i have error :
AttributeError: type object 'ContactRelation' has no attribute 'c'
The relationship function is a part of Relationship API of SQLAlchemy ORM package. It provides a relationship between two mapped classes. This corresponds to a parent-child or associative table relationship.
The sqlalchemy backref is one of the type keywords and it passed as the separate argument parameters which has to be used in the ORM mapping objects. It mainly includes the event listener on the configuration attributes with both directions of the user datas through explicitly handling the database relationships.
How do I join two tables in Sqlalchemy? Python Flask and SQLAlchemy ORM Now we use the join() and outerjoin() methods. The join() method returns a join object from one table object to another. For example, following use of join() method will automatically result in join based on the foreign key.
Thanks to Michel and Simon on SQLAlchemy mailing list i need association_proxy and two relation to Contact relation.
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')
Your relationship is not correctly designed. A secondary should be an ordinary table, not a mapped class. If you want the extra data (relation_type) on your ContactRelation, you should use the Association Table pattern described in the SQLAlchemy Relationship docs: http://docs.sqlalchemy.org/en/rel_1_1/orm/basic_relationships.html#association-object
Self-referential many-to-many relationship with Association Object.
User Class:
class User(Base):
__tablename__ = "User"
id = Column(String(36), primary_key=True, default=lambda : str(uuid1()))
Association Class:
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))
Access the relationship objects with
someUser.ignored_list
or
someUser.ignored_by_list
Thanks to Sean
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With