Удаление и повторное добавление детей базы данных при редактировании

#python #sqlalchemy

Вопрос:

У меня есть база данных, которая имеет отношение «один-много». Я буду называть это «родитель-дитя». У меня есть графический интерфейс для управления значениями в базе данных. Графический интерфейс позволяет добавлять или удалять дочерние элементы или обновлять информацию о родителе. Дочерние элементы представлены в таблице графического интерфейса. Когда пользователь хочет создать новые отношения между родителями и детьми, форма проста. Я создаю родителя, и для каждого ребенка, которого пользователь добавляет в таблицу, я добавляю его в список, например:

 parent.children.append(child) 
 

Если пользователь хочет удалить, я выполняю:

 parent.children.remove(child) 
 

Если пользователь хочет сохранить, зафиксируйте информацию, которую он ввел в форму, он нажимает сохранить, и я выполняю с помощью sqlalchemy:

 import db 
db.session.add(parent)
db.session.commit() # Also sends inserts for children 
 

Проблема в том, что мне нужно, чтобы пользователь позже обновил эту информацию. То, что я сейчас делаю (я думаю, что это должен быть умный способ или элегантный, или использование SQLAlchemy), — это загрузка детей в память, установка вспомогательной переменной с именем initial_children, например:

 import copy 
children = db.session.query(Child).all() 
self.children = db.session.query(Child).all()
self.inital_children = copy.deepcopy(self.children)
 

Затем, когда пользователь добавляет или удаляет дочерние элементы, я выполняю соответствующую операцию над переменной self.children, а позже, когда пользователь нажимает сохранить, я выполняю такой метод, как:

 def save(self):
    if self.inital_children != self.children and : 
        prompt('save changes ?') == prompt.YES:
             self.deleteInitialChildren()
             self.addNewChildren()
    self.closeGUI()
 

Я подозреваю, что SQLAlchemy должна предоставлять структуры для этого варианта использования, например, чтобы иметь только один список self.children, а при фиксации умело удалять старых детей и вставлять новых, но не смог найти решение в документах ( у меня пока нет глубокого понимания orm).

Ответ №1:

Установка каскада «Удалить-сирота» для отношения в родительском классе гарантирует, что дочерние элементы будут удалены, если они не назначены их родителю.

Если у вас есть эти модели

 class Parent(Base):
    __tablename__ = 'parent'
    id = sa.Column(sa.Integer, primary_key=True)
    children = orm.relationship("Child", cascade='all, delete-orphan')


class Child(Base):
    __tablename__ = 'child'
    id = sa.Column(sa.Integer, primary_key=True)
    parent_id = sa.Column(sa.Integer, sa.ForeignKey('parent.id'))
 

затем делаем

 parent.children = some_new_children
 

удалит все существующие дочерние parent элементы, в которых их нет some_new_children .

Комментарии:

1. Вот как я это реализовал. Я нашел ответ несколько дней назад, но, спасибо.