【问题标题】:flask sqlalchemy column constraint for positive integer正整数的烧瓶 sqlalchemy 列约束
【发布时间】:2018-01-10 03:36:29
【问题描述】:

如何使用flask sqlalchemy 将列定义为正整数?

我希望答案看起来像这样:

class City(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    population = db.Column(db.Integer, positive=True)
    def __init__(self,population):
        self.population = population

然而,这个类定义会抛出一个错误 b/c sqlalchemy 不知道“肯定”参数。

如果对象被实例化为人口的负值,我可能会引发异常。但我不知道如何确保更新后人口保持积极。

感谢您的帮助。

【问题讨论】:

    标签: python sqlalchemy flask-sqlalchemy


    【解决方案1】:

    不幸的是,在 python 方面,sqlalchemy 尽最大努力不碍事;没有“特殊的 sqlalchemy”方式来表示实例属性必须满足某些约束:

    >>> class Foo(Base):
    ...     __tablename__ = 'foo'
    ...     id = Column(Integer, primary_key=True)
    ...     bar = Column(Integer)
    ...
    >>> f = Foo()
    >>> f.bar = "not a number!"
    >>> f.bar
    'not a number!'
    

    如果您尝试提交此对象,sqlalchey 抱怨,因为它不知道如何将提供的 python 值呈现为列类型Integer 的 SQL。

    如果这不是您想要的,您只是想确保不良数据不会到达数据库,那么您需要一个 Check 约束。

    class Foo(Base):
        __tablename__ = 'foo'
        id = Column(Integer, primary_key=True)
        bar = Column(Integer)
        __table_args__ = (
            CheckConstraint(bar >= 0, name='check_bar_positive'),
            {})
    

    【讨论】:

    • bar >= 0 应称为check_bar_non_negative。对于check_bar_positive,我希望bar > 0
    【解决方案2】:

    我知道这很旧,但就其价值而言,我的方法是使用marshmallow(反序列化和数据验证库)来验证输入数据。

    为您的模型创建架构,如下所示:

    from marshmallow import validate, fields, Schema
    
    ... 
    
    class CitySchema(Schema):
        population = fields.Integer(validate=validate.Range(min=0, max=<your max value>))
    

    然后在适当的时候使用您的架构来序列化/反序列化数据:

    ... 
    city_data = {...} # your city's data (dict)
    city_schema = CitySchema()
    deserialized_city, validation_errors = city_schema.load(city_data) # validation done at deserialization
    ... 
    

    使用反序列化库的优点是您可以在一个地方强制执行所有数据完整性规则

    【讨论】:

    • 虽然这是一个选项,而且恕我直言,它作为一种补充非常有效,但最好在数据层定义数据约束,以免坏数据通过其他方式泄漏。即,验证错误,您编写了一个脚本来手动创建数据,各种其他极端情况。
    猜你喜欢
    • 2021-12-22
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多