当前位置: 首页 > 面试题库 >

什么时候需要使用sqlalchemy back_populates?

羊舌胡非
2023-03-14
问题内容

当我尝试按照本指南进行SQLAlchemy Relation
Example时:基本关系模式

我有这个代码

#!/usr/bin/env python
# encoding: utf-8
from sqlalchemy import create_engine
from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///:memory:', echo=True)
Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base(bind=engine)

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

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parent.id'))
    parent = relationship("Parent")

Base.metadata.create_all()

p = Parent()
session.add(p)
session.commit()
c = Child(parent_id=p.id)
session.add(c)
session.commit()
print "children: {}".format(p.children[0].id)
print "parent: {}".format(c.parent.id)

它运作良好,但是在指南中,该模型应为:

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")**

为什么我不需要back_populatesbackref在我的示例中?什么时候应该使用其中一个?


问题答案:

如果使用backref,则无需在第二个表上声明关系。

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

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parent.id'))

如果
使用backref,并分别定义relationship,则如果不使用back_populates,则sqlalchemy将不知道如何连接关系,因此修改一个也将修改另一个。

因此,在您的示例中,您已经relationship单独定义了,但未提供back_populates参数,修改一个字段不会自动更新事务中的另一个字段。

>>> parent = Parent()
>>> child = Child()
>>> child.parent = parent
>>> print(parent.children)
[]

看看它是如何没有自动填写该children字段的?

现在,如果提供back_populates参数,则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")

所以现在我们得到

>>> parent = Parent()
>>> child = Child()
>>> child.parent = parent
>>> print(parent.children)
[Child(...)]

Sqlalchemy知道这两个字段现在是相关的,并且将随着彼此的更新而更新。值得注意的是,使用backref也可以做到这一点。back_populates如果您想在每个类上定义关系,那么使用很好,因此很容易看到所有字段都只是浏览模型类,而不必查看通过backref定义字段的其他类。



 类似资料:
  • 问题内容: 我对JAX-WS进行了概述,并注意到了(和)的一些引用。 在什么情况下需要?(我认为JSR 109服务器?!) 问题答案: 是使用SUN的参考实现将Web服务作为标准存档部署在非Java EE5 Servlet容器上时所需的专有部署描述符。 Sun的RI 用作servlet上下文事件的侦听器和调度程序servlet。两者都必须在中声明。然后需要该文件为定义Web服务端点,以使其知道必须

  • 问题内容: 我使用类只有很短的时间,编写方法时,我使所有变量都引用了self,例如self.foo。 但是,我在浏览《 wxPython in Action》 一书时发现,“ self”并没有一直使用。例如: 下面的一个确实使用“自我”。 如果我没记错的话,“自我”是指该类的特定实例,那么什么时候没有必要?有一般的经验法则吗? 问题答案: 您用于引用当前实例的属性。 您用于引用父类的方法。 如果仅

  • 谷歌正在通过电子邮件通知Android位置权限的更改: 我们将于2016年10月15日进行更改,这将影响针对API版本21(Android 5.0、Lollipop)或更高版本的应用程序,这些应用程序使用ACCESS_FINE_LOCATION但没有明确具有“android.hardware.location.gps”用途功能。展望未来,这些应用程序将可安装在没有GPS硬件的设备上。在大多数情况下

  • 问题内容: 我如何使用AtomicBoolean?该类的作用是什么? 问题答案: 当有多个线程需要检查并更改布尔值时。例如: 这不是线程安全的。您可以使用以下方法修复它:

  • 在回答“亚马逊DynamoDB吞吐量是如何计算和限制的?”有人建议,只要超出每秒预配的吞吐量,DynamoDB就会限制请求。然而,这与我的经验相矛盾。 我在一个表中发布了多行,通常行数远远超过了配置的写容量。这种情况会在短时间内发生。在某一点上,我甚至有5分钟的平均时间超过了规定的容量。OTOH,平均15分钟低于容量。在那段时间里,我没有收到任何限制性的请求。 15分钟的平均峰值远低于规定的容量: