On Thu, Apr 26, 2018 at 11:04 AM, Diego Quintana <daquinta...@gmail.com> wrote: > Hello. > > Say I have three tables in a declarative fashion, `Parent`, `Child`, and > `Pet`, in such way that > > * `Parent` has a many-to-many relationship with both `Child` and `Pet`, > meaning that a Parent can own a Child and its pets, and also a Pet without > its Child. > * `Child` has a one-to-many relationship with `Pet` > > The code for them is (using Flask-SQLAlchemy, although I believe the > solution lives in the realm of SQLAlchemy rather than in Flask). > > class Parent(db.Model): > __tablename__ = 'parents' > > id = db.Column(db.Integer, primary_key=True) > name = db.Column(db.String(64)) > > # many to many relationship between parent and children > # my case allows for a children to have many parents. Don't ask. > children = db.relationship('Child', > secondary=parents_children_relationship, > backref=db.backref('parents', > lazy='dynamic'), > lazy='dynamic') > > # many to many relationship between parents and pets > pets = db.relationship('Pet', > secondary=users_pets_relationship, > backref=db.backref('parents', > lazy='dynamic'), # > lazy='dynamic') > > # many to many relationship between parents and children > parents_children_relationship = > db.Table('parents_children_relationship', > db.Column('parent_id', db.Integer, db.ForeignKey('parents.id')), > db.Column('child_id', db.Integer, db.ForeignKey('children.id')), > UniqueConstraint('parent_id', 'child_id')) > > # many to many relationship between User and Pet > users_pets_relationship = db.Table('users_pets_relationship', > db.Column('parent_id', db.Integer, db.ForeignKey('parents.id')), > db.Column('pet_id', db.Integer, db.ForeignKey('pets.id')), > UniqueConstraint('parent_id', 'pet_id')) > > class Child(db.Model): > __tablename__ = 'children' > id = db.Column(db.Integer, primary_key=True) > name = db.Column(db.String(64)) > # parents = <backref relationship with User model> > > # one to many relationship with pets > pets = db.relationship('Pet', backref='child', lazy='dynamic') > > > class Pet(db.Model): > __tablename__ = 'pets' > id = db.Column(db.Integer, primary_key=True) > name = db.Column(db.String(64)) > # child = backref relationship with cities > child_id = db.Column(db.Integer, db.ForeignKey('children.id'), > nullable=True) > # parents = <relationship backref from User> > > > > I would like to do something like this > > parent_a = Parent() > child_a = Child() > pet_a = Pet() > > > > I can then do this > > parent_a.children.append(child_a) > # commit/persist data > parent_a.children.all() # [child_a] > > > > I would like to achieve something like this > > child_a.pets.append(pet_a) > parent_a.children.append(child_a) > # commit/persist data > parent_a.children.all() # [child_a] > parent_a.pets.all() # [pet_a], because pet_a gets > # automatically added to parent using some sorcery > # like for child in parent_a.children.all(): > # parent.pets.append(child.pets.all()) > # or something like that. > > I can achieve this with a method in the Parent object like > add_child_and_its_pets(), but I would like to override the way relationship > works, so I don't need to override other modules that may benefit from this > behaviour, like Flask-Admin for instance. > > > Basically how should I override the backref.append method or the > relationship.append method to also append other objects from other > relationships at call time i.e. on the python side? How should I override > the remove methods as well?
this seems like coordination of two separate relationships, so use attribute events for that, http://docs.sqlalchemy.org/en/latest/orm/events.html?highlight=attributeevent#sqlalchemy.orm.events.AttributeEvents : @event.listens_for(Parent.children, "append") def _append_pets(parent, child, initiator): parent.pets.extend(child.pets) # or whatever it is you need you would need to look at the "append" and "remove" events. > > > I have also posted this question in Stack Overflow, in case it means > something. > > > Best! > > > > -- > SQLAlchemy - > The Python SQL Toolkit and Object Relational Mapper > > http://www.sqlalchemy.org/ > > To post example code, please provide an MCVE: Minimal, Complete, and > Verifiable Example. See http://stackoverflow.com/help/mcve for a full > description. > --- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sqlalchemy+unsubscr...@googlegroups.com. > To post to this group, send email to sqlalchemy@googlegroups.com. > Visit this group at https://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.