在不丢失数据的情况下合并和取消合并对象的最佳方法

时间:2011-11-02 20:55:20

标签: python database django django-models schema

假设我有两个表(我使用的是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 个答案:

答案 0 :(得分:2)

就个人而言,我会选择使用django-reversion之类的解决方案。但是,如果您想创建更强大且更不依赖于第三方逻辑的内容,请向Organization和merged_into字段添加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),您可以每次创建一个新的组织实例并合并两个“父母”都进入它,复制事件而不是更新它们。这使原始事件保持原样等待回滚。这也允许将一个以上的组织合并为一个新组织。

答案 1 :(得分:0)

我的建议是一个类似差异的界面。对于每个字段,您提供要合并的对象的所有可能值。合并它们的人为每个字段选择适当的值。您可能只想显示在此视图中检测到冲突的字段。

在所有冲突的字段都为它们选择了“好”值之后。您可以创建一个新对象,将旧版本的关系分配给该对象,然后删除旧版本。

如果你正在寻找某种自动方法,我认为你很难找到一个,即使你这样做,也不是一个好主意。每当你合并任何东西时,你需要一个人在中间。即使是同步联系人的应用程序也不会尝试自行处理冲突。

答案 2 :(得分:0)

我认为有一个关键的黑客。

组织将拥有通常的id字段,以及另一个'别名'领域。 '别名'字段将是逗号分隔的ID。在该领域,您将跟踪可能在现实世界中指向相同组织的组织。我们假设有一个名为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,'