Flask 对具有给定值的多个列的唯一约束
假设我有两张桌子 订单表Flask 对具有给定值的多个列的唯一约束,flask,sqlalchemy,flask-sqlalchemy,Flask,Sqlalchemy,Flask Sqlalchemy,假设我有两张桌子 订单表 class Order(db.Model): id = db.Column(db.Integer, primary_key=True) deliveries = db.relationship("Delivery", back_populates="order") 交货台 class Delivery(db.Model): id = db.Column(db.Integer, primary_key=True)
class Order(db.Model):
id = db.Column(db.Integer, primary_key=True)
deliveries = db.relationship("Delivery", back_populates="order")
交货台
class Delivery(db.Model):
id = db.Column(db.Integer, primary_key=True)
status= db.Column(db.String(20))
order_id = db.Column(db.Integer, db.ForeignKey('order.id'), nullable=False)
order = db.relationship("Order", back_populates="deliveries")
一个订单可能有多个交货。交货表的状态字段具有以下可能值[“计划”、“失败”、“已交货”]
问题:
如何确保一个订单没有两次计划交货
提示:
我知道我可以在多个表上实施唯一约束,比如在交付模式中添加下线
\uuuu表参数(db.UniqueConstraint('order\u id','status',name=''u order\u status\u uc'))
但通过这样做,我将防止一个订单出现两次交付失败
非常感谢您提供的任何帮助,因为我希望直接在数据库中实施此约束。您可以使用当前订单id和计划状态查询您的交货模型,如果有结果,请进行验证
planned_delivery_exist_boolean = db.session.query(Delivery).filter(Delivery.order_id==order_id).filter(Delivery.status=="Planned").first()
if planned_delivery_exist_boolean:
# trigger validation error
更新(假定为PostgreSQL)
如果您使用PostgreSQL,最简单的解决方案是:
创建唯一索引_order_status_uc ON delivery(order_id),其中status='Planned'代码>
如果使用SQLAlchemy创建索引,则以下内容应等效:
课程交付(基本):
#
原始答案
假设您使用的RDBMS支持这一点,一种实现思想是如下所示:
- 在
delivery
表上创建一个计算列,该列的“计划”状态的值为order\u id
,否则为NULL
- 在此计算列上创建一个
唯一约束
这假设了以下关于所用RDBMS的情况:
计算列不仅受支持,而且可以是索引/约束的一部分
唯一索引的实现允许多个NULL
值
请参阅文章了解更多背景。您正在使用的数据库引擎是什么?我正在使用PostgreSQL我相信有人会想到一个约束更宽松的解决方案。如果使用PostgreSQL,则在订单id上使用状态为“计划”的部分唯一索引。
?我打赌这就是为什么您已经询问了DBMS。到目前为止,我没有找到一个非常适合的约束实现。这个提议是一个变通办法,我接受了。非常感谢@vanThis只能在ORM级别工作。我想要一些关于数据库级别的东西,这是我为什么要寻找db约束的原因
__table_args__ = (
Index(
'_order_status_uc',
'order_id',
unique=True,
postgresql_where=(status == 'Planned'),
),
)