如何根据 SqlAlchemy 关系设置模型默认值?

Posted

技术标签:

【中文标题】如何根据 SqlAlchemy 关系设置模型默认值?【英文标题】:How can I set model defaults based on a SqlAlchemy relationship? 【发布时间】:2018-05-23 04:36:18 【问题描述】:

假设我有以下模型:

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 默认为 Treatment.treatment_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 字段。

【问题讨论】:

由于客户可以进行多种处理(和许多发货),您如何决定发货从哪个处理开始? 实际上,我们使用基于treatment_date的最早治疗。为了简单起见,我将代码更改为仅使用索引 0。 【参考方案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)

【讨论】:

以上是关于如何根据 SqlAlchemy 关系设置模型默认值?的主要内容,如果未能解决你的问题,请参考以下文章

如何将sqlalchemy中列的默认值设置为关系中列的值?

您如何设置 sqlalchemy 关系ihp,以便子查询负载将根据属性过滤我们的结果

SQLAlchemy docs(设置列默认值) - 这行语法有效的python如何? [关闭]

如何在sqlalchemy before_insert事件中添加模型的关系实例?

为啥 sqlalchemy 没有正确设置默认值?

导入关系中使用的 SQLAlchemy 模型?