约束引用多态模型的列

时间:2016-04-14 22:04:03

标签: python database postgresql sqlalchemy flask-sqlalchemy

我有三个模型跟随单表继承(Car,BlueCar,RedCar)和一个与RedCar有关系的模型RedCarUser。我希望有一个限制,防止使用BlueCar id创建RedCarUser,更简洁:

redcar = RedCar(model="toyota")
bluecar = BlueCar(model="mazda")

# I want this to work
user = RedCarUser(name="Bob", car_id=redcar.id)

# But this to fail
user = RedCarUser(name="Bob", car_id=bluecar.id)

# Currently they are both allowed.

这就是模型的设置方式:

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.dialects.postgres import ENUM
from sqlalchemy.orm import relationship

from base import Base
from enum import Enum


class Colors(Enum):
    RED = 'Red'
    BLUE = 'Blue'


class Car(Base):
    colors_enum = ENUM(
        Colors.BLUE.value,
        Colors.RED.value,
        name='car_colors'
    )

    id = Column(Integer, primary_key=True)
    model = Column(String(255), nullable=False)
    color = Column(colors_enum, nullable=False, server_default=Colors.BLUE.value)

    __tablename__ = "cars"
    __mapper_args__ = {
        'polymorphic_on': color,
    }

    def __init__(self, model, color=Colors.BLUE.value):
        self.model = model
        self.color = color


class BlueCar(Car):
    __mapper_args__ = {
        'polymorphic_identity': Colors.BLUE.value
    }

    def __init__(self, model, color=Colors.RED.value):
        super(RedCar, self).__init__(model, color)


class RedCar(Car):
    __mapper_args__ = {
        'polymorphic_identity': Colors.RED.value
    }

    users = relationship('RedCarUser', back_populates='car')

    def __init__(self, model, color=Colors.RED.value):
        super(RedCar, self).__init__(model, color)


class RedCarUser(Base):
    __tablename__ = "red_car_users"

    id = Column(Integer, primary_key=True)
    name = Column(String(255), nullable=False)
    car_id = Column(Integer, ForeignKey(RedCar.id), nullable=False)

    car = relationship('RedCar', foreign_keys=[car_id])

    def __init__(self, name, car_id):
        self.name = name
        self.car_id = car_id

0 个答案:

没有答案