Меня всегда смущает, как и когда я могу создавать объекты вместе со своими детьми.
У меня есть заказ, который имеет один ко многим для LineItems и OrderTags, я хочу создать все это вместе. У меня было ощущение, что я должен быть в состоянии сделать
Order(
...
line_items=[LineItem(...) for i in line_items],
tags=[OrderTags(value="foobar")]
)
session.add(order)
session.commit()
, и это сработало бы, но line_item.order_id
s не устанавливаются, а OrderTags
терпят неудачу полностью
Iдумаю, это может иметь какое-то отношение к тому, действительно ли line_item.order_id
объявляется как FK и как устанавливаются отношения. Вот соответствующие части модели и фактический код, пытающийся создать объекты.
class OrderTag(Base, BaseModelMixin):
__tablename__ = "order_tags"
id = Column(INTEGER(11), nullable=False, unique=True)
order_id = Column(ForeignKey("orders.id", ondelete="CASCADE", onupdate="CASCADE"), primary_key=True, nullable=False)
value = Column(String(45), primary_key=True, nullable=False)
created_at = Column(DateTime, nullable=False, server_default=text("CURRENT_TIMESTAMP"))
order = relationship("Order", uselist=True, back_populates="order_tags")
class LineItem(Base):
"""
Line Item Model
"""
"""Reflect Table"""
__tablename__ = "line_items"
id = Column(INTEGER(11), nullable=False, index=True)
partner_line_item_id = Column(String(45), primary_key=True, nullable=False, index=True)
account_id = Column(String(9), primary_key=True, nullable=False)
shop_name = Column(String(128), primary_key=True, nullable=False)
order_id = Column(INTEGER(11), index=True)
....
order = relationship(
"Order", uselist=False, back_populates="line_items", primaryjoin="Order.id == foreign(LineItem.order_id)"
)
class Order(Base, BaseModelMixin, PostCommitTriggersModelMixin, SanitizationModelMixin):
"""
Order Model
"""
__tablename__ = "orders"
id = Column(INTEGER(11), nullable=False, unique=True) # for some reason the autoincrement isn't here, but it definitely is on the DB
account_id = Column(INTEGER(6), primary_key=True, nullable=False, index=True)
order_number = Column(String(32), primary_key=True, nullable=False, index=True)
shop_name = Column(String(128), primary_key=True, nullable=False, index=True, server_default=text("''"))
account = relationship("Account", uselist=False, primaryjoin="Account.id == foreign(Order.account_id)")
line_items = relationship("LineItem", back_populates="order", primaryjoin="Order.id == foreign(LineItem.order_id)")
line_items = []
for lid in line_item_data:
line_item = LineItem(**lid)
line_items.append(line_item)
order = Order(
....
line_items=line_items,
order_tags=[OrderTag(value="foobar"),
)
session.add(order)
session.commit()
In [14]: order.line_items
[]
In [15]: LineItem.query().filter(LineItem.order_id == None).all()
Out[15]:
[<LineItem id:307280084, partner_line_item_id:4, account_id:48, order_number:None, order_id:None, ...>]
Это работает, если я вместо этого сделаю следующее:
order = Order(...)
session.add(order)
session.commit()
line_items = []
for lid in line_item_data:
line_items.append(LineItem(**lid)
order.line_items.extend(line_items)
session.commit()
order.order_tags.extend([OrderTag(value='foobar')])
session.commit()