Для sqlalchemy возможно добавить правило уровня поля, что два конкретных столбца не могут быть оба Нет? - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть модель, которая выглядит так:

class Foo(db.Model):

    id = db.Column(db.Integer, primary_key=True)

    # omitted lengthy codes...

    spam = db.relationship('Spam')
    spam_id = db.Column(db.Integer, db.ForeignKey('spams.id'))

    bar = db.relationship('Bar')
    bar_id = db.Column(db.Integer, db.ForeignKey('bars.id'))

    created = db.Column(db.DateTime, server_default=db.func.now())

Есть ли какие-либо опции, доступные для Flask-SQLAlchemy, чтобы добавить поведение, при котором spam_id и bar_id не могут быть одновременно None во время вставки / обновления? Но примет, если хотя бы один из этих столбцов имеет значение.

1 Ответ

0 голосов
/ 12 сентября 2018

Вы можете использовать ограничение таблицы здесь

from sqlalchemy import CheckConstraint


class Foo(db.Model):

    id = db.Column(db.Integer, primary_key=True)

    # omitted lengthy codes...

    spam = db.relationship('Spam')
    spam_id = db.Column(db.Integer, db.ForeignKey('spams.id'))

    bar = db.relationship('Bar')
    bar_id = db.Column(db.Integer, db.ForeignKey('bars.id'))

    created = db.Column(db.DateTime, server_default=db.func.now())

    __table_args__ = (
        CheckConstraint('NOT(spam_id IS NULL AND bar_id IS NULL)', name='both_null'),
    )

Пытаетесь добавить новый экземпляр Foo с spam_id с помощью None? Хорошо, вы можете

foo=Foo(spam_id=None, bar_id=1)
sqlalchemy_session.add(foo)
sqlalchemy_session.commit()

Пытаетесь добавить Foo с spam_id и bar_id в None? Нет, сэр!

foo=Foo(spam_id=None, bar_id=None)
sqlalchemy_session.add(foo)
sqlalchemy_session.commit()  # Raises Exception

Возникло исключение из вашей СУБД, например, с PostgresQL и драйвером psycopg2 это psycopg2.IntegrityError

...