猿问

为什么我需要多对一关系的关系和外键?

在SQLAlchemy for Many to One关系的文档中,它显示了以下示例:


class Parent(Base):

    __tablename__ = 'parent'

    id = Column(Integer, primary_key=True)

    child_id = Column(Integer, ForeignKey('child.id'))

    child = relationship("Child")


class Child(Base):

    __tablename__ = 'child'

    id = Column(Integer, primary_key=True)

许多父母为独生子女。那么,当我们创建 a 时Parent,我们需要填充child_idand child,这似乎有点多余?这是强制性的,还是每件事的目的是什么?


child = Child()

Parent(child_id=child, child=child)

此外,在 Flask-SQLAlchemy 中,有一个简单关系的例子,它创建了一个像这样的帖子:


Post(title='Hello Python!', body='Python is pretty cool', category=py)

不提供category_id. 如果我复制该场景,则category_id值为None.


为了创建像 的新对象Parent(child=child),添加foreign_keys=[child_id]是否足够,或者它是否有进一步的含义?


森林海
浏览 129回答 1
1回答

繁星淼淼

这不是强制性的;您不需要同时填充两者。将外键设置为相关实例可能是一个等待自身出现的错误。你唯一需要做的就是child = Child()parent = Parent(child=child)在这之后parent.child_id是None,但它们代表ORM的对象部分就好了。parent.child是对创建的引用child。除了它们的 Python 对象 ID 之外,它们还没有被持久化到数据库并且没有身份。只有当您将它们添加到 aSession并将更改刷新到数据库时,它们才会收到身份,因为它们使用生成的代理键。这是从对象世界到关系世界的映射发生的地方。SQLAlchemy 会自动填写parent.child_id,以便他们的关系也记录在数据库中(注意这不是关系模型中的“关系”的意思)。回到示例,添加一些打印有助于跟踪发生的情况和时间:child = Child()parent = Parent(child=child)print(parent.child_id)  # Nonesession.add(parent)session.flush()  # Send changes held in session to DBprint(parent.child_id)  # The ID assigned to child您也可以颠倒这种情况:您可能拥有现有Child对象的 ID ,但没有实际对象的 ID 。在这种情况下,您可以简单地分配给child_id自己。所以,回答标题:您不需要 ORMrelationship来拥有 DB 外键关系,但您可以使用它来将 DB 关系映射到对象世界。
随时随地看视频慕课网APP

相关分类

Python
我要回答