Лучший способ объединять и удалять объекты без потери данных - PullRequest
3 голосов
/ 03 ноября 2011

Скажем, у меня есть две таблицы (я использую Django, но этот вопрос в основном не зависит от языка):

Organization(models.Model):
    name = models.CharField(max_length=100)

Event(models.Model):
    organization = models.ForeignKey(Organization)
    name = models.CharField(max_length=100)  

Пользователи могут создавать как события, так и организации. Существует вероятность того, что два отдельных пользователя создадут объекты организации, которые должны напоминать одну и ту же реальную организацию. Когда кто-то замечает эту проблему, он должен объединить два объекта, чтобы была только одна организация.

Вопрос, который у меня возникает, заключается в следующем: как объединить эти две организации, чтобы обеспечить их «удаление», если пользователь их неправильно слил? Таким образом, простое решение удаления одного из объектов Организации и указания всех событий на другой не является вариантом. Я ищу очень руководящие указания по передовому опыту здесь.

Несколько возможных решений:

  • Добавьте еще одну таблицу, объединяющую организации, которые были «объединены», и таким образом отслеживайте слияния
  • Добавить поле внешнего ключа в Organization, чтобы указать организацию, с которой оно было объединено
  • Сохраните копии всех исходных объектов такими, какими они были до слияния, используя что-то вроде django-reversion

Ответы [ 3 ]

2 голосов
/ 06 ноября 2011

Лично я бы пошел с решением, которое использует что-то вроде django-reversion. Однако, если вы хотите создать что-то более надежное и менее зависимое от логики стороннего производителя, добавьте поле merged_into в Organization и поле merged_from в Event:

Organization(models.Model):
    name = models.CharField(max_length=100)
    merged_into = models.ForeignKey('self', null=True, blank=True)

Event(models.Model):
    organization = models.ForeignKey(Organization)
    name = models.CharField(max_length=100)  
    merged_from = models.ForeignKey(Organization null=True, blank=True)

При слиянии вы также можете выбрать обновить события. Отныне обязательно перенаправляйте все ссылки организаций "merged_into" в новую организацию.

Если вы хотите разрешить несколько слияний (например: A + B в C, A + C в D, E + F в G и D + G в H), вы можете каждый раз создавать новый экземпляр организации и объединять оба «родители» в нее копируют события, а не обновляют их. Это сохраняет исходные события без изменений в ожидании отката. Это также позволяет объединить более двух организаций в одну за один шаг.

0 голосов
/ 07 ноября 2011

Я думаю, что есть ключ взлома.

У организации будет обычное поле идентификатора и другое поле псевдонимов.Поле 'aliases' будет разделено запятыми.В этой области вы будете отслеживать организации, которые могут указывать на то же самое в реальном мире.Предположим, что существует 2 организации с именем organization_1, organization_2 и id 1, 2.

organization_1           organization_2
_id = 1                  _id = 2
aliases = '1, 2'         aliases = '2, 1'

Если вы хотите запросить события, которые принадлежат только Organization_1, вы можете это сделать.Если вы хотите запросить все события Organization_1, Organization_2, вы проверите его, если поле псевдонимов содержит ключ.Возможно, разделитель должен быть не просто ',', он также должен окружать поле псевдонимов в целом.Что-то вроде ', 1,2,'.Таким образом, мы можем убедиться, что он содержит ', id,'

0 голосов
/ 03 ноября 2011

Мое предложение будет похожим на diff интерфейсом. Для каждого поля вы указываете все возможные значения объединяемых объектов. Человек, объединяющий их, выбирает подходящее значение для каждого поля. Возможно, вы захотите показать только поля, в которых был обнаружен конфликт в этом представлении.

После того, как для всех конфликтующих полей было выбрано «хорошее» значение. Вы создаете новый объект, назначаете отношения из старых версий этому и удаляете старые версии.

Если вы ищете какой-то автоматический подход, я думаю, вам будет сложно его найти, и даже если вы это сделаете, это не будет хорошей идеей. Каждый раз, когда вы объединяете что-либо, вам нужен человек в середине Даже приложения, синхронизирующие контакты и тому подобное, не пытаются самостоятельно разрешать конфликты.

...