sqlalchemy back_populates はいつ使用する必要がありますか? 質問する

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? どちらか一方をいつ使用すればよいですか?

ベストアンサー1

使用する場合、backref2 番目のテーブルで関係を宣言する必要はありません。

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'))

もしあなたが〜ならないを使用してbackrefrelationshipを個別に定義した場合、 を使用しないとback_populates、sqlalchemy は関係を接続する方法を認識できず、一方を変更するともう一方も変更されます。

relationshipしたがって、を個別に定義したが引数を指定しなかった例では、back_populates1 つのフィールドを変更しても、トランザクション内の他のフィールドは自動的に更新されません。

>>> 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 は、これら 2 つのフィールドが関連していることを認識し、もう一方のフィールドが更新されると、それぞれを更新します。 usingbackrefでも同じことが行われることに注意してください。 using はback_populates、すべてのクラスで関係を定義する場合に便利です。これにより、backref を介してフィールドを定義する他のクラスを確認する必要がなくなり、モデル クラスをざっと見るだけですべてのフィールドを簡単に確認できます。

おすすめ記事