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