合并和取消合并对象而不丢失数据的最佳方法
假设我有两个表(我正在使用 Django,但这个问题主要与语言无关):
Organization(models.Model):
name = models.CharField(max_length=100)
Event(models.Model):
organization = models.ForeignKey(Organization)
name = models.CharField(max_length=100)
允许用户创建事件和组织。两个不同的用户有可能创建类似于同一现实世界组织的组织对象。当有人注意到这个问题时,他们应该能够合并两个对象,这样就只有一个组织。
我的问题是:如何合并这两个组织,以确保如果用户错误地合并了它们,我可以“取消合并”它们?因此,删除一个组织对象并将所有事件指向另一个组织对象的简单解决方案不是一种选择。我正在寻找关于最佳实践的非常高水平的指南。
一些可能的解决方案:
- 添加另一个表,将已“合并”的组织连接在一起,并以这种方式跟踪合并情况
- 在组织上添加外键字段以指向与其合并的组织 将
- 所有原始对象的副本保留为它们在合并之前就存在,使用类似 django-reversion
Say I have two tables (I am using Django, but this question is mostly language agnostic):
Organization(models.Model):
name = models.CharField(max_length=100)
Event(models.Model):
organization = models.ForeignKey(Organization)
name = models.CharField(max_length=100)
Users are allowed to create both events and organizations. There is the chance that two separate users create organization objects that are supposed to resemble the same real world organization. When someone notices this problem, they should be able to merge the two objects so there is only one organization.
The question I have is this: How do I merge these two organizations in order to ensure I can "unmerge" them if the user incorrectly merged them? Thus, the simple solution of deleting one of the Organization objects and pointing all Events to the other one is not an option. I am looking for very high level guidelines on best practices here.
A few possible solutions:
- Add another table that joins together organizations that have been "merged" and keep track of merges that way
- Add a foreign key field on Organization to point to an organization it was merged with
- Keep copies of all of the original objects as they existed before a merge, using something like django-reversion
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
就我个人而言,我会选择使用 django-reversion 之类的解决方案。但是,如果您想创建更强大且更少依赖于第 3 方逻辑的内容,请将
merged_into
字段添加到 Organization,将merged_from
字段添加到 Event:合并时,您可以选择也更新事件。从现在开始,请务必将“merged_into”组织的所有引用重定向到新组织。
如果您想允许多次合并(例如:A + B 到 C、A+C 到 D、E+F 到 G、D+G 到 H),您可以每次创建一个新的组织实例并合并两个“父组织实例” " 到其中,复制事件而不是更新它们。这使原始事件保持完整,等待回滚。这还允许一步将 2 个以上组织合并为一个新组织。
Personally, I would go with a solution which uses something like
django-reversion
. However, if you want to create something more robust and less dependent on 3rd party logic, add amerged_into
field to Organization andmerged_from
field to Event:On merge, you can choose update the events as well. From now on, be sure to redirect all references of "merged_into" organizations into the new organization.
If you want to allow multiple merges (for example: A + B into C, A+C into D, E+F into G and D+G into H), you can create a new organization instance each time and merge both "parents" into it, copying the events instead of updating them. This keeps the original events intact waiting for a rollback. This also allows merging more than 2 organizations into a new one in one step.
我的建议是一个类似 diff 的界面。对于每个字段,您提供正在合并的对象中的所有可能值。合并它们的人为每个字段选择适当的值。您可能只想显示在此视图中检测到冲突的字段。
毕竟所有冲突的字段都为它们选择了“良好”的值。您创建一个新对象,将旧版本的关系分配给该对象,然后删除旧版本。
如果您正在寻找某种自动方法,我认为您将很难找到一种方法,即使您找到了,这也不是一个好主意。任何时候你要合并任何东西,你都需要一个人在中间。即使是同步联系人等的应用程序也不会尝试自行处理冲突。
My suggestion would be a diff-like interface. For each field, you provide all the possible values from the objects being merged. The person merging them chooses the appropriate value for each field. You'd probably only want to show fields on which a conflict was detected in this view.
After all conflicting fields have had a "good" value chosen for them. You create a new object, assign relationships from the old versions to that one, and delete the old versions.
If you're looking for some sort of automatic approach, I think you'd be hard pressed to find one, and even if you did, it would not really be a good idea. Any time you're merging anything you need a human in the middle. Even apps that sync contacts and such don't attempt to handle conflicts on their own.
我认为有一个关键的黑客攻击。
组织将具有常用的 id 字段和另一个“别名”字段。 “别名”字段将是逗号分隔的 ID。在该字段中,您将跟踪现实世界中可能指向相同目标的组织。假设有一个名为organization_1、organization_2的2个组织,id为1、2。
如果您想查询仅属于organization_1的事件,您可以这样做。如果要查询organization_1、organization_2的所有事件,则检查aliases字段是否包含该key。也许分隔符不应该只是“,”,它还应该围绕整个别名字段。类似于“,1,2,”。这样我们就可以确保检查它是否包含',id,'
I think there is a key hack.
Organization will have usual id field, and an another 'aliases' field. 'aliases' field would be comma separated ids. In that field you'll track the organizations that may be pointing to the same in real world. Let's say there was a 2 organization named organization_1, organization_2 and id is 1, 2.
If you want to query event's that is only belong to organization_1, you can do it. If you want to query all events of organization_1, organization_2, you check it if aliases field contains the key. Maybe separator should be not just ',' it should also surround aliases field a whole. Something like ',1,2,'. In this way we can be sure to check if it contains ',id,'