Django-сигналы против триггеров?

Я читал о сигналах django (http://docs.djangoproject.com/en/dev/topics/signals/), но, насколько я понимаю, сигналы никогда не преобразуются в литературные триггеры SQL (http://en.wikipedia.org/wiki/Database_trigger).

Если я прав, что сигналы и триггеры различны, то какой из них лучше и какими способами? Какая лучшая практика?

....................

Вот конкретный пример, если вы хотите его:

class Location(models.Model):
    name = models.CharField(max_length=30)

class Person(models.Model):
    location = models.ForeignKey('Location')

class Team(models.Model):
    locations = models.ManyToManyField('Location')

Я хочу, чтобы человек мог присоединиться к команде в том и только в том случае, если это место находится в пределах этого набора команд. Я не знаю, как это сделать с нормальными реляционными ограничениями, насколько я знаю, я вынужден использовать триггеры или сигналы. Моя кишка говорит, что я должен использовать триггеры, но я хочу знать лучшие практики.

Ответ 1

Ни. Лучшим инструментом для этой работы является проверка модели - вы можете написать свое собственное правило проверки, и оно будет применено в администраторе и ваших собственных приложениях.

Ответ 2

Сигналы Django потрясающие (проверка тоже потрясающая, но иногда вам нужно что-то изменить перед сохранением…). Если вы работаете с базой данных ТОЛЬКО через Django, неплохо было бы хранить всю логику в одном месте, imho.

Вот пример того, как это работает:

class Example(models.Model):
    ''' Example of Model (I hate foo-bars!) '''
    age = models.IntegerField()
    can_buy_beer = models.BooleanField(default=False)


def set_can_buy_beer(sender, instance, **kwargs):
    ''' Trigger body '''
    if instance.age >= 21:
        instance.can_buy_beer = True
    else:
        instance.can_buy_beer = False

# ↓ Magic — now, field Example.can_buy_beer will be autocalculated on each save!
pre_save.connect(set_can_buy_beer, sender=Example) 

Ответ 3

Вы можете использовать триггеры для принудительного применения таких ограничений, но я бы не стал на это полагаться. Это можно сделать только в качестве вторичного принудительного исполнения, в то время как первичный - это проверка модели, как уже сказал Даниэль.

Что касается триггеров DB против сигналов Django, они более разные. Единственная распространенная вещь, которую они разделяют, заключается в том, что оба вызываются при изменении сущности. Но сущности сильно отличаются.

Триггеры отслеживают изменения строки базы данных, поэтому они работают с необработанными табличными данными. Триггерный код запускается СУБД.

В отличие от триггеров, сигналы отслеживают изменения объекта домена. В общем случае модель Django состоит из данных из нескольких строк таблицы (рассмотрим наследование модели и связанные с ней подмножества объектов). Сигнальный код запускается Django.

Ответ 4

Основные преимущества триггеров над сигналами:

  • не зависит от приложения: упрощает переход на новые фреймворки/языки (поскольку триггеры и, в некоторых случаях, хранимые процедуры сбрасываются с вашей БД)

  • безопасность: в зависимости от ситуации вы можете ограничить права UPDATE для некоторых таблиц и по-прежнему иметь возможность запускать ваше приложение (подумайте о критической истории или таблицах транзакций, которые знают, какие эксплойты могут быть обнаружены в ближайшие 10 лет)

  • уменьшить количество запросов, которые ваше приложение должно адресовать к СУБД (особенно полезно в контексте распределенной архитектуры).

Вот основные преимущества. Основным недостатком является то, что вам приходится иметь дело с синтаксисом SQL старой школы.