Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python sqlalchemy中的覆盖关系行为_Python_Python 3.x_Sqlalchemy_Flask Sqlalchemy_Relationships - Fatal编程技术网

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
它们的代码是(使用Flask SQLAlchemy,尽管我相信解决方案存在于SQLAlchemy领域,而不是Flask)

我可以这样做

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
)

如果您愿意,您也可以非常合理地创建一个backref
parent
,这将允许您访问
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)