SQLAlchemy验证多个属性上的装饰器

时间:2018-11-20 14:30:01

标签: python postgresql sqlalchemy flask-sqlalchemy

我对我的两个属性使用了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,那就可以了。 显然,有一些案例可能会以相反的顺序出现问题。

有更好的解决方案吗?

0 个答案:

没有答案