我想拥有由用户编辑的,使用Django存储的大文本字段的完整历史记录。

我看过这些项目:

  • Django Full History (Google Code)
  • Django ModelHistory
  • Django FullHistory

  • 我有一个特殊的用例,可能超出了这些项目提供的范围。此外,我对这些项目的文档记录,测试和更新程度保持警惕。无论如何,这是我面临的问题:

    我有一个模特,就像这样:
    from django.db import models
    
    class Document(models.Model):
       text_field = models.TextField()
    

    此文本字段可能很大-超过40k-我想拥有一种自动保存功能,该功能每30秒左右保存一次该字段。显然,如果每个保存40k(如果压缩的话,可能仍然保存10k),则该数据库可能会变得非常庞大。我能想到的最好的解决方案是在最新保存的版本和新版本之间保持差异。

    但是,我担心涉及并行更新的竞争条件。我想到了两个不同的种族条件(第二个条件比第一个条件严重得多):
  • HTTP事务竞争条件:用户A和用户B请求文档X0,并分别进行更改,从而生成Xa和Xb。 Xa被保存,X0和Xa之间的差异为“Xa-0”(“少而不是”),现在Xa作为正式版本存储在数据库中。如果Xb随后保存,它将覆盖Xa,差异为Xb-a(“b减去a”)。

    虽然不理想,但我并不太担心这种行为。这些文档相互覆盖,并且用户A和B可能彼此都不知道(每个人都从文档X0开始),但是历史记录保持完整性。
  • 数据库读取/更新竞争条件:有问题的竞争条件是Xa和Xb同时保存在X0上的情况。将会有(伪)代码,例如:
     def save_history(orig_doc, new_doc):
         text_field_diff = diff(orig_doc.text_field, new_doc.text_field)
         save_diff(text_field_diff)
    

    如果Xa和Xb都从数据库中读取X0(即orig_doc为X0),则它们的差异将变为Xa-0和Xb-0(与序列化的Xa-0然后Xb-a相反,或者等效为Xb-0然后Xa- b)。当您尝试将所有差异修补在一起以生成历史记录时,它将在修补程序Xa-0或Xb-0(均适用于X0)上均失败。历史的完整性已受到损害(或已经受到损害?)。

    一种可能的解决方案是自动对帐算法,该算法可以事后检测到这些问题。如果重建历史记录失败,则可以假定发生了争用情况,因此将失败的补丁应用于历史记录的先前版本,直到成功为止。

  • 我很高兴收到一些有关如何解决该问题的反馈和建议。

    顺便说一句,至于这是一个有用的出路,我注意到这里讨论了Django原子性:
  • Django: How can I protect against concurrent modification of data base entries,这里:
  • Atomic operations in Django?

  • 非常感谢你。

    最佳答案

    存储问题:我认为您应该只存储文档的两个连续有效版本的差异。如您所指出的,当同时进行编辑时,问题就变成了获得有效的版本。

    并发问题:

  • 是否可以像Jeff suggests或通过锁定文档来避免它们全部在一起?
  • 如果没有,我认为您最终将成为在线协作实时编辑器(例如Google Docs )的范例。

  • 要获取蠕虫 jar 的图解 View ,请打开catch this google tech-talk at 9m21s (这是有关Eclipse的协作实时编辑的)

    或者,有一些专利详细说明了如何处理Wikipedia article on collaborative real-time editors上的这些并发问题。

    关于django - 如何在Django中输入完整的历史记录?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/420749/

    10-11 04:53