What is the difference between SQLAlchemy back_populates and backref? What happens if I don't write either of them? The story.
To write from the conclusion,
(1) When backref is used It automatically creates a two-way relationship.
(2) When back_populates is used You need to create a two-way relationship yourself.
(3) When neither back_populates nor backref is used Reversed fields are not automatically updated during a transaction.
It turns out that.
Let's look at a concrete example. Consider the Event model and Ticket model as examples. One Event has multiple Tickets, a One to Many relationship.
class Event(Base):
__tablename__ = 'event'
id = Column(Integer, primary_key=True)
title = Column(String(255))
tickets = relationship("Ticket",backref="event")
class Ticket(Base):
__tablename__ = 'ticket'
id = Column(Integer,primary_key=True)
title = Column(String(255))
value = Column(Integer)
event_id = Column(Integer,ForeignKey('event.id'))
event = Event(title="test")
ticket = Ticket(title="test_ticket",value=5000)
event.tickets = [ticket]
event.tickets #Ticket Objects
ticket.event #Event Object
When using back_populates, it will not work unless you have a bidirectional relationship.
class Event(Base):
__tablename__ = 'event'
id = Column(Integer, primary_key=True)
title = Column(String(255))
tickets = relationship("Ticket",back_populates="event")
class Ticket(Base):
__tablename__ = 'ticket'
id = Column(Integer,primary_key=True)
title = Column(String(255))
value = Column(Integer)
event_id = Column(Integer,ForeignKey('event.id'))
event = relationship("Event",back_populates="tickets")
event = Event(title="test")
ticket = Ticket(title="test_ticket",value=5000)
event.tickets = [ticket]
event.tickets #Ticket Objects
ticket.event #Event Object
class Event(Base):
__tablename__ = 'event'
id = Column(Integer, primary_key=True)
title = Column(String(255))
tickets = relationship("Ticket")
class Ticket(Base):
__tablename__ = 'ticket'
id = Column(Integer,primary_key=True)
title = Column(String(255))
value = Column(Integer)
event_id = Column(Integer,ForeignKey('event.id'))
event = relationship("Event")
event = Event(title="test")
ticket = Ticket(title="test_ticket",value=5000)
event.tickets = [ticket]
event.tickets #Ticket Objects
ticket.event #None
In this case, ticket → event is None. In other words, it can be seen that the event is not associated with the ticket in the transaction. Of course, after the transaction ends (after inserting the event object), it is linked in both directions.
event = self.session.query(Event).filter(Event.id==1).one()
ticket = self.session.query(Ticket).filter(Ticket.id==1).one()
event.tickets #Ticket Objects
ticket.event #Event Object
Recommended Posts