SQLAlchemy «один ко многим»: ограничить родителя как минимум одним ребенком - PullRequest
0 голосов
/ 06 мая 2019

Предположим, у меня есть простое сопоставление SQLAlchemy:

class Parent(db.Model)
    id = db.Column(db.Integer, primary_key=True)
    children = db.relationship('Child', back_populates='parent')

class Child(db.Model)
    id = db.Column(db.Integer, primary_key=True)
    parent_id = db.Column(db.Integer, db.ForeignKey('parent.id'), nullable=False)
    parent = db.relationship('Parent', back_populates='children')

В этой форме это Один (родитель)-ко-многим (детям) .

Из-за флага nullable каждый Child должен иметь Parent, иначе IntegrityError повышается. [Обратите внимание, что по умолчанию не каскадное «удаление» или «удаление-сирота» гарантирует, что при удалении родителя его дочерние элементы не также удаляются, следовательно, ошибка]

Тем не менее, я хочу поднять IntegrityError, когда у Parent есть ноль детей . То есть:

  • Создание нового Parent без создания и указания хотя бы одного Child запрещено.
  • Удаление последних Child в коллекции Parent s children запрещено.

Есть ли способ сделать это в Postgres (и SQLite 3 в разработке)?

1 Ответ

1 голос
/ 06 мая 2019

Чтобы сделать его независимым от базы данных, вы можете использовать события sqlalchemy для проверки родителей перед вставкой:

from sqlalchemy import event


@event.listens_for(Parent, 'before_insert')
@event.listens_for(Parent, 'before_update')
def receive_before_insert_or_update(mapper, connection, parent):

    if not parent.children:
        # you should probably use your own exception class here
        raise IntegrityError("Parent without children not allowed")

Это предотвратит вставку или обновление родителя с / без детей. Вы можете использовать тот же шаблон с событием before_delete, чтобы предотвратить удаление детей.

...