Как установить значения по умолчанию для модели на основе отношения SqlAlchemy?

Допустим, у меня есть следующие модели:

class Customer(Model):
    __tablename__ = 'customer'
    id = Column(Integer())
    treatments = relationship('Treatment', back_populates='customer')
    shipments = relationship('Shipment', back_populates='customer')

class Treatment(Model):
    __tablename__ = 'treatment'
    customer_id = Column(Integer(), ForeignKey('customer.id'))
    customer = relationship('Customer', back_populates='treatments')
    treatment_date = Column(DateTime(), nullable=False)

class Shipment(Model):
    __tablename__ = 'shipment'
    customer_id = Column(Integer(), ForeignKey('customer.id'))
    customer = relationship('Customer', back_populates='shipments')
    ship_date = Column(DateTime(), nullable=False)

Я бы хотел, чтобы по умолчанию для Shipment.ship_date было задано за день до даты обращения с обработкой. Другими словами, я хочу сделать следующее:

customer = Customer()
treatment = Treatment(treatment_date="11/02/2017")
customer.treatments.append(treatment)
shipment = Shipment()
customer.shipments.append(shipment)
shipment.ship_date
# 11/01/2017

Как мне установить значения по умолчанию на основе отношений, когда они устанавливаются динамически с помощью таких методов, как append?


Для пояснения, это вопрос о SqlAlchemy и когда устанавливаются отношения. Например, я попробовал следующее:

class Shipment(Model):
    # ...same set up as above
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.ship_date = self.customer.treatments[0].treatment_date - timedelta(1)

Но это бросает TypeError, потому что SqlAlchemy не настроил self.customer поле еще.

1 ответ

Решение

Похоже, что SQLAlchemy не настраивает отношения в обоих направлениях до тех пор, пока модель не будет добавлена ​​и зафиксирована в сеансе.

customer.shipments.append(new_shipment)
customer.shipments # includes the new shipment
new_shipment.customer # None
session.add(customer)
session.commit()
new_shipment.customer # <Customer object>

Хотя это раздражает, и я не уверен, почему SQLAlchemy не заполняет двусторонние отношения, когда создается одна сторона, это можно решить, вручную установив отношения с обеих сторон. Например:

new_shipment = Shipment(customer=customer)
new_shipment.ship_date # 11/01/2017
customer.shipments.append(new_shipment)
Другие вопросы по тегам