3

データベース内のすべての情報を含む中央の Django サーバーがあります。2 番目のデータベースにその情報のサブセットを含む 2 番目の Django サーバーが必要です。2 つの間でデータを選択的に同期する防弾の方法が必要です。

  • セカンダリ Django は、特定の時点でプライマリからデータのサブセットをプルする必要があります。サブセットは、特定のフィールドでフィルタリングする必要があります。
  • セカンダリ Django は、時々そのデータをプライマリにプッシュする必要があります。
  • 理想的には、双方向の同期により、モデルごとに最後に変更されたオブジェクトが保持されます。

TimeStampedModel (django-extensions から) を使用するか、独自の DateTimeField(auto_now=True) を追加して、すべてのオブジェクトが最終変更時刻を保存するように考えていました。次に、最近変更されたオブジェクトのみが保持されるように、1 つの DB からデータをダンプして別の DB にロードするメカニズムが考えられます。

私が考えている可能性は、django の dumpdata、django-extensions dumpscript、django-test-utils makefixture、またはおそらく django-fixture マジックです。考えなければならないことがたくさんあるので、どの道を進むべきかわかりません。

4

1 に答える 1

4

私のすべての要件に適合する私のソリューションは次のとおりです。

  1. すべてのモデルに自然キーと一意の制約を 実装する
    • 主キー ID を使用せずに各オブジェクトを一意に参照できるようにする
  2. django-extensions の TimeStampedModelから各モデルをサブクラス化します
    • 自動的に更新されるフィールドを追加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 管理コマンドを作成します。このコマンドは、シリアル化されたファイルを読み取り、次のようにオブジェクトを反復処理します。

    • オブジェクトがデータベースに存在しない場合 (自然キーによる)、作成します
    • オブジェクトが存在する場合は、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

于 2013-07-08T18:39:16.213 に答える