Cuando pruebo el ejemplo de relación de SQLAlchemy siguiendo esta guía: Patrones de relación básicos
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?
fuente
back_populates
vsbackref
:backref
es más sucinta porque no es necesario declarar la relación en ambas clases, pero en la práctica considero que no vale la pena guardar esto en línea. Creo queback_populates
es mejor, no solo porque en la cultura de Python "Explícito es mejor que implícito" (Zen de Python), pero cuando tienes muchos modelos, con un vistazo rápido a su declaración puedes ver todas las relaciones y sus nombres en lugar de repasar todos los modelos relacionados. Además, un buen beneficio adicionalback_populates
es que obtienes autocompletado en ambas direcciones en la mayoría de IDE =)parent_id
realmente necesario bajo Child? Y qué hay de las tablas de ayuda, como se indica en la documentaciónparent_id
es el campo de clave externa real que almacena la relación padre-hijo. Es necesario. Las tablas auxiliares sirven para definir relaciones de varios a varios (por ejemplo, si un hijo puede tener más de un padre). El ejemplo de fkey anterior es el ejemplo clásico de uno a manay donde cada hijo tiene un solo padre y un padre puede tener muchos hijos.