qnica
Март 6, 2015 11:44:56
Добрый день.
Подскажите как в SQLAlchemy создать дерево категорий в которых нельзя было бы удалить не пустую категорию?
Т.е. что бы к примеру проходил такой тест:
root = Category(name='root')
category = Category(name='category', parent=root)
db.session.add(category)
db.session.commit()
db.session.delete(root)
self.assertRaises(IntegrityError, db.session.commit)
4kpt_III
Март 6, 2015 13:24:10
Самое простое решение - предварительно выбирать для удаления только те записи у которых нет children.
Хотя вообще можно покопать в сторону настроек cascade relationship`a.
qnica
Март 6, 2015 13:37:35
В сторону cascade relationship копаю вторые сутки. Уже и методом тыка перебираю. Пока не получается. В джанговских моделях можно в таком случае поставить так:
class Category(models.Model):
name = models.CharField(max_length=140)
parent = models.ForeignKey(
'self', related_name="sub_categories",
null=True, blank=True, on_delete=models.PROTECT)
Вот думаю как сделать аналогично для SQLAlchemy моделей.
sander
Март 6, 2015 23:03:49
а if не решает проблему?
4kpt_III
Март 6, 2015 23:12:26
sander
Да я тоже написал, что проще постанализ делать, чем городить дополнительную логику в модели. Не есть это гуд. Или просто при выборе объекта из БД для удаления сразу отсекать объекты у которых есть children…
qnica
Март 11, 2015 10:24:18
4kpt_III,
sanderСпасибо за ответы. На основе них решил повесить событие на удаление категории
@db.event.listens_for(Category, 'before_delete')
def receive_before_delete(mapper, connection, target):
"""
Вызвать исключение при попытки удалить категорию содержащую объекты.
"""
if target.sub_categories:
raise IntegrityError("Can't delete not empty category", None, None)
Правда не уверен на счет
но вроде не критичено.
sander
Март 11, 2015 10:27:23
а смысл вешать ексепш и оборачивать запрос в try-except?
qnica
Март 11, 2015 10:57:07
sander
Что бы не делать чепочку проверок через if.
К примеру при попытке удалить категорию которая содержит объекты вылетит ошибка. По анологии решил сделать и при удалении категории.
Т.е. в одном try-except сразу проверять целостность данных и двигаться дальше, либо сообщить об этом пользователю.
qnica
Март 11, 2015 11:09:56
Хотя не уверен что правильно вызывать IntegrityError на уровне логики приложения…
4kpt_III
Март 11, 2015 12:27:33
Много ли мест, где в приложении будет вызываться удаление категории?