我对我的两个属性使用了sqlalchemy验证器装饰器,如下所示:
@validates('start_time', 'duration')
def validate_times(self, key, value):
if self.obj:
# then attached object is not transient under creation, so we can validate
# validate start time
if self.start_time < self.obj.start_time:
raise IntegrityError('item start time is before the obj start time', None, None)
# validate end time
if self.start_time + dt.timedelta(minutes=self.duration) > self.obj.end_time:
raise IntegrityError('item end time is after the obj end time', None, None)
return value
基本上有第二个数据库obj
(一种父obj),它具有开始和结束时间,此验证的目的是确保此特定item
的开始和结束时间在其父级的父级内。
这是一种相当安全的方法,因为我不认为它会破坏完整性,但是由于属性验证的顺序是随机的,因此即使应该没有属性验证,它也有可能引发IntegrityError
。即它不会产生误报,但可能会产生误报。
请考虑以下情况:
obj.start_time = 0
obj.end_time = 10
item.start_time = 8
item.duration = 1 # -> implied end_time is 9 and all lies between 0<8<9<10.
obj.start_time = 0
obj.end_time = 10
item.start_time = 2
item.duration = 3 # -> implied end_time is 5 and is valid since 0<2<5<10
但是,它不是同时验证,而是顺序验证,因此
如果duration
首先被验证,则自(old_8+new_3 = 11 > 10)
起将导致错误。但是在这种情况下,如果首先验证start_time
,那就可以了。
显然,有一些案例可能会以相反的顺序出现问题。
有更好的解决方案吗?