Python 我什么时候需要使用 sqlalchemy back_populates?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39869793/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 22:50:21  来源:igfitidea点击:

When do I need to use sqlalchemy back_populates?

pythonsqlalchemy

提问by Liqang Lau

When I try SQLAlchemy Relation Example following this guide: Basic Relationship Patterns

当我按照本指南尝试 SQLAlchemy 关系示例时:基本关系模式

I have this code

我有这个代码

#!/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)

It works well, but in the guide, it says the model should be:

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

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

Why don't I need back_populatesor backrefin my example? When should I use one or the other?

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

回答by Brendan Abel

If you use backrefyou don't need to declare the relationship on the second table.

如果使用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'))

If you're notusing backref, and defining the relationship's separately, then if you don't use back_populates, sqlalchemy won't know to connect the relationships, so that modifying one also modifies the other.

如果您使用backref, 并relationship单独定义's ,那么如果您不使用back_populates,sqlalchemy 将不知道连接关系,因此修改一个也会修改另一个。

So, in your example, where you've defined the relationship's separately, but didn't provide a back_populatesargument, modifying one field wouldn't automatically update the other in your transaction.

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

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

See how it didn't automatically fill out the childrenfield?

看到它没有自动填写children字段吗?

Now, if you supply a back_populatesargument, sqlalchemy will connect the fields.

现在,如果您提供一个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")

So now we get

所以现在我们得到

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

Sqlalchemy knows these two fields are related now, and will update each as the other is updated. It's worth noting that using backrefwill do this, too. Using back_populatesis nice if you want to define the relationships on every class, so it's easy to see all the fields just be glancing at the model class, instead of having to look at other classes that define fields via backref.

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