SQLalchemy中的backref和back_populate概念?

Boo*_*ity 7 python database sqlalchemy

谁能解释这两个想法的概念,以及它们与表之间的关系如何?我似乎真的找不到任何能清楚解释它的内容,并且文档觉得简单概念中的术语太多了。例如,在文档中的一对多关系示例中:

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    children = relationship("Child", back_populates="parent")

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parent.id'))
    parent = relationship("Parent", back_populates="children")
Run Code Online (Sandbox Code Playgroud)

为什么relationship()进入父类而ForeignKey进入子类?back_populates彼此之间到底有什么作用?relationship()函数在哪个类中是否存在?

小智 52

backref是一种快捷方式,用于仅在父类或子类(而不是两者)的一个地方配置parent.childrenchild.parent relationships。也就是说,而不是拥有

children = relationship("Child", back_populates="parent")  # on the parent class
Run Code Online (Sandbox Code Playgroud)

parent = relationship("Parent", back_populates="children")  # on the child class
Run Code Online (Sandbox Code Playgroud)

你只需要其中之一:

children = relationship("Child", backref="parent")  # only on the parent class
Run Code Online (Sandbox Code Playgroud)

或者

parent = relationship("Parent", backref="children")  # only on the child class
Run Code Online (Sandbox Code Playgroud)

children = relationship("Child", backref="parent").parent自动在子类上创建关系。在另一方面,如果你使用back_populates,你必须明确地建立relationship在两家母公司和子类秒。

为什么relationship() 在父类里面,而ForeignKey 在子类里面?

正如我上面所说的,如果你使用back_populates,它需要在父类和子类中进行。如果您使用backref,则只需要使用其中之一。ForeignKey需要上子类,不管relationship放在哪里,这是关系数据库的一个基本概念。

back_populates 到底对彼此有什么影响?

back_populates通知每个关系关于另一个,以便他们保持同步。例如,如果你这样做

p1 = Parent()
c1 = Child()
p1.children.append(c1)
print(p1.children)  # will print a list of Child instances with one element: c1
print(c1.parent)  # will print Parent instance: p1
Run Code Online (Sandbox Code Playgroud)

如您所见,即使您没有明确设置它,它也p1被设置为父级c1

关系()函数存在于哪个类的位置是否重要?

这仅适用于backref,不可以,您可以将关系放在父类 ( children = relationship("Child", backref="parent")) 或子类 ( parent = relationship("Parent", backref="children")) 上并具有完全相同的效果。

  • @Zaffer 回复:“目前哪种做法更好?” - 截至 2022 年 7 月,“backref”[被视为遗留](https://docs.sqlalchemy.org/en/14/orm/backref.html),并且“back_populates”是首选。 (13认同)
  • @Zaffer Back_populates 实际上更好理解,因为您可以在两个表上看到它们的关系。如果您只使用 backref,并且仅在子级上声明了它,则您将看不到与父级相关的其他表,反之亦然。 (3认同)
  • 放置 backref 决定了一对多关系的“一”方,不是吗? (2认同)

u2g*_*les 15

显然,应首选使用back_populates显式relationship()构造,如下所示:

https://docs.sqlalchemy.org/en/14/orm/backref.html

  • 是的。当在父模型和子模型上定义关系时,还可以更容易地理解代码。 (2认同)