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

时间:2017-12-08 21:53:06

标签: python sqlalchemy sqlalchemy-utils

我们说我有以下型号:

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字段。

1 个答案:

答案 0 :(得分:0)

似乎SQLAlchemy在添加模型并将其提交到会话之前不会双向配置关系。

Enter your favorite number: 11.1

Enter an integer!

Exception in thread "main" Enter your favorite number: java.util.InputMismatchException
    at java.util.Scanner.throwFor(Unknown Source)
    at java.util.Scanner.next(Unknown Source)
    at java.util.Scanner.nextInt(Unknown Source)
    at java.util.Scanner.nextInt(Unknown Source)
    at RobB.FavoriteNum.main(FavoriteNum.java:21)

虽然这很烦人,但我不确定为什么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>