2013-06-28 105 views
2

我有一个中央的Django服务器,它包含了我在数据库中的所有信息。我想要第二个Django服务器在第二个数据库中包含这些信息的一个子集。我需要一种防弹的方式来选择性地同步两者之间的数据。在两台Django服务器之间同步数据

  • 辅助Django需要在特定时间从主服务器提取其数据的子集。子集将不得不被某些字段过滤。
  • 辅助Django将不得不偶尔将其数据推送到主数据库。
  • 理想情况下,双向同步将保留每个模型的最近修改的对象。

我想沿着使用TimeStampedModel(从Django的扩展),具有或加入我自己的DateTimeField字段(auto_now = TRUE),这样每个对象存储它的最后修改时间线的东西。然后,可能会有一种机制来转储来自一个数据库的数据并将其加载到另一个数据库中,以便只保留最近修改的对象。

我正在考虑的可能性是django的dumpdata,django-extensions dumpscript,django-test-utils makefixture或者django-fixture magic。有很多事情需要考虑,所以我不确定要走下去的路。

+1

您可以在数据库级别执行此操作吗? (例如,如果你正在使用postgres,通过编写pg_dump/pg_restore脚本所需的脚本)如果你需要防弹的东西,那可能会更安全一些。 – bitgarden

+0

在你的主django服务器上创建一个辅助连接并称之为从服务器。编写一个及时运行的cron/celery脚本,并使用默认连接从您的表中获取数据,并使用从属连接保存它们..请参阅https://gist.github.com/bofh19/5887902 – boltsfrombluesky

+0

这些方法能够通过时间戳同步两个数据库? –

回答

2

这里是我的解决方案,它适合我的所有要求:

  1. 所有车型的
    • 允许用于指每个对象以独特的方式实现natural keys和唯一约束不使用主键标识
  2. Sublcass从TimeStampedModel每个模型在Django的扩展
    • 再添自动更新createdmodified领域
  3. 创建导出Django的管理命令,它过滤数据的一个子集,并用自然键

    baz = Baz.objects.filter(foo=bar) 
    yaz = Yaz.objects.filter(foo=bar) 
    
    objects = [baz, yaz] 
    flat_objects = list(itertools.chain.from_iterable(objects)) 
    
    data = serializers.serialize("json", flat_objects, indent=3, use_natural_keys=True) 
    print(data) 
    
  4. 其序列创建导入Django的管理命令,其读取序列化文件并如下遍历对象:

    • 如果对象不存在exis吨数据库(自然键),创建
    • 如果对象存在,检查modified时间戳
    • 如果导入的对象是新的,更新的领域
    • 如果导入的对象是年纪大了,不更新(但是要打印警告)

代码示例:

# Open the file 
with open(args[0]) as data_file: 
    json_str = data_file.read() 

# Deserialize and iterate 
for obj in serializers.deserialize("json", json_str, indent=3, use_natural_keys=True): 

    # Get model info 
    model_class = obj.object.__class__ 
    natural_key = obj.object.natural_key() 
    manager = model_class._default_manager 

    # Delete PK value 
    obj.object.pk = None 

    try: 
     # Get the existing object 
     existing_obj = model_class.objects.get_by_natural_key(*natural_key) 

     # Check the timestamps 
     date_existing = existing_obj.modified 
     date_imported = obj.object.modified 
     if date_imported > date_existing: 

      # Update fields 
      for field in obj.object._meta.fields: 
       if field.editable and not field.primary_key: 
        imported_val = getattr(obj.object, field.name) 
        existing_val = getattr(existing_obj, field.name) 
        if existing_val != imported_val: 
         setattr(existing_obj, field.name, imported_val) 

    except ObjectDoesNotExist: 
     obj.save() 

的工作流程这是先拨打python manage.py exportTool > data.json,然后在另一个django实例(或相同)上,拨打python manage.py importTool data.json

相关问题