언제 sqlalchemy back_populates를 사용해야합니까?

이 가이드에 따라 SQLAlchemy 관계 예제를 시도 할 때 : 기본 관계 패턴

이 코드가 있습니다

#!/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_populates또는 backref내 예? 둘 중 하나를 언제 사용해야합니까?



답변

사용 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를 통해 필드를 정의하는 다른 클래스를 볼 필요없이 모든 필드가 모델 클래스를 훑어 보는 것을 쉽게 볼 수 있습니다.


답변