Использовать одну таблицу связей ManyToMany вместо поля ManyToMany & ForeignKey на нескольких моделях? - PullRequest
1 голос
/ 03 февраля 2020

У меня есть приложение Django, которое обрабатывает рабочие процессы анализа данных, с моделями баз данных, которые выглядят примерно так:

class Workflow(models.Model):
    execution_id = models.UUIDField()

class WorkflowItem(models.Model):
    workflow = models.ForeignKey(Workflow)
    type = models.CharField(choices=["input", "output"])
    files = models.ManyToManyField(File)

class File(models.Model):
    path = models.CharField()

class FileMetadata(models.Model):
    metadata = models.JSONField()
    file = models.ForeignKey(File)
    version = models.IntegerField()

У данного Workflow будет много WorkflowItem, что соответствует File, которые могут использоваться WorkflowItem во многих Workflow. Каждый File может иметь много связанных FileMetadata, из которых запись с максимальным значением version обычно используется для данной операции.

По мере роста приложения становится все труднее создавать все различные комбинации логик c, необходимые для поиска записей в одной таблице на основе заданной записи в другой таблице, просто используя каждую таблицу. Интерфейс внешнего ключа (Workflow <-> WorkflowItem <-> File <-> FileMetadata).

Я рассматриваю вопрос о создании таблицы, в которой хранятся все внешние ключи для всех отношений в одном месте. Примерно так:

class WorkflowFile(models.Model):
    workflow = models.ForeignKey(Workflow)
    workflow_item = models.ForeignKey(WorkflowItem)
    file = models.ForeignKey(File)
    file_metadata = models.ForeignKey(FileMetadata)

Однако я не уверен, хорошая это идея или нет. Мне не ясно, выгодна ли реализация подобной таблицы по сравнению с простым отслеживанием всех связей внешнего ключа для каждой таблицы. Мне также не ясно, как мне настроить такую ​​таблицу с помощью Django, и если новое требование для ручного ввода значений в эту таблицу все время перевесит уменьшенную потребность в уникальных логиках запросов c каждый раз, когда я хочу запросить эти отношения. Моя конечная цель - предоставить более простой и последовательный способ получить все элементы отношения на основе любых других элементов отношения.

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

1 Ответ

1 голос
/ 04 февраля 2020

Не уверен, что это действительно ответит на ваш вопрос, но если вы хотите go способ с несколькими FK, то вы можете рассмотреть возможность использования таблицы от до в сочетании с m2m измененным сигналом на добавьте соответствующие FK к этой модели после добавления записей M2M в WorkflowItem.

Это будет что-то вроде:

from django.db.models.signals import m2m_changed

class WorkflowItem(models.Model):
    workflow = models.ForeignKey(Workflow)
    type = models.CharField(choices=["input", "output"])
    files = models.ManyToManyField(File, through=IntermediateTable)

class IntermediateTable(models.Model):
    file = models.ForeignKey(File, related_name='file')
    workflow_item = models.ForeignKey(WorkflowItem, related_name='worflowitem')
    workflow = models.ForeignKey(Workflow, null=True)
    file_metadata = models.ForeignKey(FileMetadata)

def workflow_item_changed(sender, **kwargs):
    sender.workflow = sender.workflow_item.workflow
    ...
    sender.save()

m2m_changed.connect(workflow_item_changed, sender=WorkflowItem.files.through)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...