복붙노트

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

PYTHON

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

이 가이드 다음에 나오는 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_populates 나 backref가 필요하지 않은 이유는 무엇입니까? 둘 중 하나를 사용해야합니까?

해결법

  1. ==============================

    1.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를 사용하지 않고 관계를 별도로 정의하는 경우 back_populates를 사용하지 않으면 sqlalchemy는 관계를 연결하는 것을 알 수 없으므로 하나를 수정해도 다른 관계가 수정됩니다.

    따라서 관계를 별도로 정의했지만 back_populates 인수를 제공하지 않은 예제에서는 한 필드를 수정해도 트랜잭션에서 자동으로 다른 필드가 업데이트되지 않습니다.

    >>> parent = Parent()
    >>> child = Child()
    >>> child.parent = parent
    >>> print parent.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는이 두 필드가 지금 관련되어 있고 다른 하나가 업데이트됨에 따라 각각을 업데이트한다는 것을 알고 있습니다. 역 참조를 사용하면이 작업을 수행 할 수 있습니다. 모든 클래스에서 관계를 정의하려면 back_populates를 사용하는 것이 좋습니다. 따라서 backref를 통해 필드를 정의하는 다른 클래스를 살펴 보는 대신 모델 클래스에서 모든 필드를 쉽게 볼 수 있습니다.

  2. from https://stackoverflow.com/questions/39869793/when-do-i-need-to-use-sqlalchemy-back-populates by cc-by-sa and MIT license