python - query - ¿Cuándo necesito usar sqlalchemy back_populate?
sqlalchemy query (1)
Si usa
backref
, no necesita declarar la relación en la segunda tabla.
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''))
Si
no
usa
backref
y define las
relationship
por separado, entonces si no usa
back_populates
, sqlalchemy no sabrá conectar las relaciones, de modo que modificar una también modifica la otra.
Entonces, en su ejemplo, donde definió la
relationship
por separado, pero no proporcionó un argumento
back_populates
, la modificación de un campo no actualizaría automáticamente el otro en su transacción.
>>> parent = Parent()
>>> child = Child()
>>> child.parent = parent
>>> print parent.children
[]
¿Ves cómo no completó automáticamente el campo secundario?
Ahora, si proporciona un argumento
back_populates
, sqlalchemy conectará los campos.
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")
Entonces ahora tenemos
>>> parent = Parent()
>>> child = Child()
>>> child.parent = parent
>>> print parent.children
[Child(...)]
Sqlalchemy sabe que estos dos campos están relacionados ahora y actualizará cada uno a medida que se actualiza el otro.
Vale la pena señalar que usar
backref
lo hará.
Usar
back_populates
es bueno si desea definir las relaciones en cada clase, por lo que es fácil ver que todos los campos solo miren la clase de modelo, en lugar de tener que mirar otras clases que definen campos a través de refref.
Cuando trato de SQLAlchemy Relation Example siguiendo esta guía: Patrones básicos de relación
Tengo este codigo
#!/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)
Funciona bien, pero en la guía, dice que el modelo debería ser:
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")**
¿Por qué no necesito
back_populates
o
backref
en mi ejemplo?
¿Cuándo debo usar uno u otro?