Ограничение столбца sqlalchemy для положительного целого числа

как я могу определить столбец как положительное целое число, используя колбу 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

однако это определение класса вызовет ошибку, потому что sqlalchemy не знает о «положительном» аргументе.

я мог бы вызвать исключение, если объект создается с отрицательным значением для населения. но я не знаю, как гарантировать, что популяция останется положительной после обновления.

спасибо за любую помощь.


person SeanPlusPlus    schedule 08.01.2013    source источник


Ответы (2)


к сожалению, со стороны 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 как SQL для типа столбца Integer.

Если это не то, что вы ищете, вы просто хотите убедиться, что неверные данные не попадут в базу данных, тогда вам нужно ограничение Check.

class Foo(Base):
    __tablename__ = 'foo'
    id = Column(Integer, primary_key=True)
    bar = Column(Integer)
    __table_args__ = (
        CheckConstraint(bar >= 0, name='check_bar_positive'),
        {})
person SingleNegationElimination    schedule 09.01.2013
comment
bar >= 0 следует называть check_bar_non_negative. Для check_bar_positive я бы ожидал bar > 0 - person Martin Thoma; 30.01.2021

Я знаю, что это устарело, но для чего бы это ни стоило, мой подход состоял в том, чтобы использовать 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
... 

Преимущество использования библиотеки де/сериализации заключается в том, что вы можете применять все свои правила целостности данных в одном месте.

person kip2    schedule 09.01.2018