Python sqlalchemy中的覆盖关系行为
假设我有三个声明性的表,Python sqlalchemy中的覆盖关系行为,python,python-3.x,sqlalchemy,flask-sqlalchemy,relationships,Python,Python 3.x,Sqlalchemy,Flask Sqlalchemy,Relationships,假设我有三个声明性的表,Parent,Child,和Pet,这样 Parent与Child和Pet Child与Pet 它们的代码是(使用Flask SQLAlchemy,尽管我相信解决方案存在于SQLAlchemy领域,而不是Flask) 我可以这样做 parent_a.children.append(child_a) # commit/persist data parent_a.children.all() # [child_a] 我想实现这样的目标 parent_a = Parent
Parent
,Child
,和Pet
,这样
与Parent
和Child
Pet
与Child
Pet
parent_a.children.append(child_a)
# commit/persist data
parent_a.children.all() # [child_a]
我想实现这样的目标
parent_a = Parent()
child_a = Child()
pet_a = Pet()
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.
我可以通过父对象中的方法实现这一点,比如添加子对象和它的宠物()
,但是我想覆盖关系的工作方式,所以我不需要覆盖其他可能从这种行为中受益的模块,例如Flask Admin
基本上,我应该如何覆盖backref.append
方法或relationship.append
方法,以便在调用时也从其他关系(即python端)附加其他对象?我应该如何重写remove
方法呢?对于parent.pets.all()
,我认为您可以将儿童作为一种条件,并将其视为一种条件
这取决于您的桌子,但看起来像:
Parent.pets = relationship(
Pet,
backref='parent'
primaryjoin=Pet.child_id == Child.id,
secondaryjoin=Child.parent_id == Parent.id
)
如果您愿意,您也可以非常合理地创建一个backrefparent
,这将允许您访问parent\u a.pets
以及pet\u.parent
,使用来自的相同答案,这可以通过,在对第一个参数中的对象调用append
或remove
之前调用
@db.event.listens_for(Parent.children, 'append')
def _append_children(parent, child, initiator):
# appends also the pets bound to the child that the
# is being appended to the Parent
parent.pets.extend(child.pets.all())
# at the end of this call, executes
# parent.children.append(child)
我正在读关于primaryjoin和secondaryjoin的书。同时,你所说的“如果你愿意,你也可以相当合理地做一个反向参考父母”是什么意思?你能举个例子吗?是否还需要显示我的代码?添加了backref
参数以显示其外观。这有用吗?
@db.event.listens_for(Parent.children, 'append')
def _append_children(parent, child, initiator):
# appends also the pets bound to the child that the
# is being appended to the Parent
parent.pets.extend(child.pets.all())
# at the end of this call, executes
# parent.children.append(child)