Уведомления

Группа в Telegram: @pythonsu

#1 Март 6, 2015 11:44:56

qnica
Зарегистрирован: 2014-01-16
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

[SQLAlchemy] Дерево категорий

Добрый день.
Подскажите как в 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)

Офлайн

#2 Март 6, 2015 13:24:10

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

[SQLAlchemy] Дерево категорий

Самое простое решение - предварительно выбирать для удаления только те записи у которых нет children.

Хотя вообще можно покопать в сторону настроек cascade relationship`a.

Офлайн

#3 Март 6, 2015 13:37:35

qnica
Зарегистрирован: 2014-01-16
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

[SQLAlchemy] Дерево категорий

В сторону 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 моделей.

Офлайн

#4 Март 6, 2015 23:03:49

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

[SQLAlchemy] Дерево категорий

а if не решает проблему?

Офлайн

#5 Март 6, 2015 23:12:26

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

[SQLAlchemy] Дерево категорий

sander

Да я тоже написал, что проще постанализ делать, чем городить дополнительную логику в модели. Не есть это гуд. Или просто при выборе объекта из БД для удаления сразу отсекать объекты у которых есть children…

Офлайн

#6 Март 11, 2015 10:24:18

qnica
Зарегистрирован: 2014-01-16
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

[SQLAlchemy] Дерево категорий

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)
Правда не уверен на счет
None, None
но вроде не критичено.

Офлайн

#7 Март 11, 2015 10:27:23

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

[SQLAlchemy] Дерево категорий

а смысл вешать ексепш и оборачивать запрос в try-except?

Офлайн

#8 Март 11, 2015 10:57:07

qnica
Зарегистрирован: 2014-01-16
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

[SQLAlchemy] Дерево категорий

sander
Что бы не делать чепочку проверок через if.

К примеру при попытке удалить категорию которая содержит объекты вылетит ошибка. По анологии решил сделать и при удалении категории.

Т.е. в одном try-except сразу проверять целостность данных и двигаться дальше, либо сообщить об этом пользователю.

Офлайн

#9 Март 11, 2015 11:09:56

qnica
Зарегистрирован: 2014-01-16
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

[SQLAlchemy] Дерево категорий

Хотя не уверен что правильно вызывать IntegrityError на уровне логики приложения…

Офлайн

#10 Март 11, 2015 12:27:33

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

[SQLAlchemy] Дерево категорий

Много ли мест, где в приложении будет вызываться удаление категории?

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version