Django数据库同步以实现离线使用

20

我有一个主Django服务器,其中数据存储在MySQL数据库中。

在线模式:我希望许多用户能够在他们的笔记本电脑上拥有与此数据库同步的副本(只需复制增量)(SQLLite DB)

离线模式(用户无法访问主服务器):用户可以查看和更新其本地数据库。

回到在线模式:在用户的笔记本电脑上修改的内容将同步回主Django服务器。

我认为,由于我有两种不同的数据库,因此我需要在Django对象级别进行同步。是否有Django应用程序可以执行此操作?如果没有,您将如何编写此功能?

3个回答

5
原来我在Django中运行了这样的系统。
这不是一个完整的答案,只是目前大部分解决问题的答案。
  • 使用UUID作为主键。这可以大大减少不同对象之间的主键冲突。
  • 使用Django的序列化框架进行数据交换。中央管理站点有一个选项,可以将所选对象下载到与Django兼容的序列化文件中。然后用户可以离线并启动本地管理站点,在那里上传序列化文件。完成离线编辑后,使用相同的过程,在“离线”管理站点将对象序列化为文件,并上传到中央管理站点。
  • 序列化框架非常有用,因为您可以获得实际(未保存的)对象,然后决定是否保存它以及在保存之前修改一些字段。
我们使用这个简单的系统遇到的问题非常少,也有助于内容适当分类,编辑人员只创建/编辑不重叠的类别。
我已经与一些人谈过这个问题,并向我提出了几种解决方案:
  • 使用时间戳字段:这有助于决定保存哪个版本和丢弃哪个版本。
  • 使用版本字段,具有主要版本号和次要版本号。次要编辑(如拼写更正)仅更新次要版本号,而主要更改会更新主要版本号并将次要版本号设置为0。这样,在比较时,您始终知道哪一个具有更高的优先级。但是,这需要编辑用户内部的教育和约定。
  • 对象更新。一个单独的模型,用于存储来自离线编辑的更新。然后,“首席”编辑将它们合并到实际对象中,并使用一些附加的管理视图查看差异(使用google-diff-match-patch等)。对象也可以被标记为允许直接更新,即不存储更新并在到达时直接应用它们。不便之处在于“首席”编辑必须审核所有更新,这取决于更新的信息量。
希望这在某种程度上有所帮助。如果有人决定实施其中的某些内容,我很乐意听取他的意见。

是的,我同意 UUID 的原则:这是让多台计算机上的对象获得相同 ID 的唯一方式。但是我需要更自动化的东西……我需要再多思考一下…… - Eric
如果你使用PostgreSQL作为关系型数据库管理系统,那么UUID是一流的数据库类型,我很喜欢。+1 - fish2000

1
我建立了一个Django应用程序来完成这个任务。当在远程/笔记本电脑版本的应用程序上创建模型实例时,它们会被标记为脏数据并获得临时ID。远程应用程序定期检查与主服务器的连接情况。当有网络连接时,即应用程序在线时,从主服务器获取每个新的脏数据模型实例的永久ID。临时ID将被替换为永久ID,然后将同步脏数据实例到主服务器。
我使用Django REST框架接收和更新主服务器上的脏数据模型实例。
请注意,这还需要在离线计算机上运行本地Web服务器。我选择了CherryPy。

1

嗯,我其实不知道是否有一个django应用程序可以做到这一点,但我会按照以下步骤进行:

创建一个“offline_update”方法:连接到服务器的数据库,选择所有id与本地数据库匹配的对象。更新本地数据库。然后选择其余的条目,并将它们添加到本地数据库中。

创建一个“online_update”方法:相同的例程,反过来执行。

优点:易于实现(Objects.all()可以获取所有内容,然后您可以直接操作和更新或保存)

缺点:竞争条件(如果两个用户同时更新同一条目怎么办?谁拥有最新的版本?)

您基本上创建了一种“mysql-svn”来保持两个数据库的更新。

我投票+1支持您的问题,因为它非常有趣。我一直通过转储数据库(通过mysql)然后加载到本地数据库中来工作,而没有使用django。


还有一个问题:我认为使用对象的主键不是一个好主意,因为许多用户可以在一些其他用户更新其离线数据库时更新主数据库,即使对于不同的对象,也可能会发生主键冲突。 - Eric
是的,我的只是一个例子,基本上“竞态条件”在任何形式下都是问题... - Samuele Mattiuzzo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接