Поддержание согласованности внешних ключей базы данных - PullRequest
0 голосов
/ 06 ноября 2018

Я пытаюсь написать приложение django с базой данных PostgreSQL. Моя проблема может быть сведена к следующему минимальному примеру:

Организация

  • имеет 0 ... N рабочих

работник

  • принадлежит организации

Задача

  • принадлежит организации
  • не назначен никому или назначен одному работнику в той же организации

Я не уверен в том, как спроектировать базу данных таким образом, чтобы предотвратить несогласованное состояние - поскольку как у Worker, так и у Task должен быть внешний ключ, указывающий на организацию, к которой они принадлежат, возможно, в результате возникнет несогласованное состояние, когда работник из организации A получает задание из организации B.

Единственное решение, которое я мог придумать, это проверка ограничения в методе сохранения:

class Organization(models.Model):
    name = models.CharField(max_length=255)


class Worker(models.Model):
    name = models.CharField(max_length=255)
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE)


class Task(models.Model):
    name = models.CharField(max_length=255)
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
    assigned_to = models.ForeignKey(Worker, null=True, on_delete=models.SET_NULL)

    def save(self, *args, **kwargs):
        if self.assigned_to and self.assigned_to.organization != self.organization:
            raise ValidationError('Task and Worker belong in different Organizations.')
        return super(Task, self).save(*args, **kwargs

Можно ли создать лучшее решение, которое по-прежнему предотвращает несогласованность состояний? Мое собственное решение не выглядит хорошим с точки зрения проектирования баз данных.

...