7

データベース A のデータの一部をシリアライズし、データベース B でデシリアライズする方法 (異なるインストール間での一種の保存/復元) を研究しており、ID の重複による問題を回避するために Djangoの自然キーを調べました。 .

唯一の問題は、カスタム マネージャーと新しいメソッドをすべてのモデルに追加する必要があることです。unique=Trueまたはunique_togheterフィールドを見て、Djangoに自然キーを自動的に生成させる方法はありますか?

4

4 に答える 4

3

この回答は Django とは何の関係もないことに注意してください。

データベースについては言及していませんが、SQL Server には、行に保持されているデータに一意の値を与えるために使用できるBINARY_CHECKSUM()キーワードがあります。行内のすべてのフィールドに対するハッシュと考えてください。このチェックサム メソッドを使用して、ローカル行のチェックサム <> リモート行のチェックサムをチェックすることにより、別のデータベースからデータベースを更新できます。

以下のこの SQL は、リモート データベースからローカル データベースを更新します。新しい行は挿入されません。そのため、使用しますinsert ... where id > @MaxLocalID

SELECT  delivery_item_id, BINARY_CHECKSUM(*) AS bc
INTO    #DI
FROM    [REMOTE.NETWORK.LOCAL].YourDatabase.dbo.delivery_item di


SELECT  delivery_item_id, BINARY_CHECKSUM(*) AS bc
INTO    #DI_local
FROM    delivery_item di

-- Get rid of items that already match
DELETE  FROM #DI_local
WHERE   delivery_item_id IN (SELECT l.delivery_item_id
                             FROM   #DI x, #DI_local l
                             WHERE  l.delivery_item_id = x.delivery_item_id
                             AND l.bc = x.bc)

DROP TABLE #DI

UPDATE  DI
SET     engineer_id = X.engineer_id,
        ... -- Set other fields here
FROM    delivery_item DI,
        [REMOTE.NETWORK.LOCAL].YourDatabase.dbo.delivery_item x,
        #DI_local L
WHERE   x.delivery_item_id = L.delivery_item_id
        AND DI.delivery_item_id = L.delivery_item_id

DROP TABLE #DI_local

上記を機能させるには、ローカル データベースとリモート データベースの間にリンク サーバーが必要です。

-- Create linked server if you don't have one already 
IF NOT EXISTS ( SELECT  srv.name
                FROM    sys.servers srv
                WHERE   srv.server_id != 0
                        AND srv.name = N'REMOTE.NETWORK.LOCAL' ) 
    BEGIN
        EXEC master.dbo.sp_addlinkedserver @server = N'REMOTE.NETWORK.LOCAL',
        @srvproduct = N'SQL Server'

        EXEC master.dbo.sp_addlinkedsrvlogin
        @rmtsrvname = N'REMOTE.NETWORK.LOCAL',
        @useself = N'False', @locallogin = NULL,
        @rmtuser = N'your user name',
        @rmtpassword = 'your password'
    END
GO
于 2010-12-21T09:24:29.273 に答える
1

私の解決策は自然キーとは何の関係もありませんが、picke/unpickleを使用します。これは最も効率的な方法ではありませんが、コードに簡単に適応できます。複雑なdb構造で動作するかどうかはわかりませんが、そうでない場合は試してみてください。

db Aに接続した場合:

import pickle
records_a = your_model.objects.filter(...) 
f = open("pickled.records_a.txt", 'wb')
pickle.dump(records_a, f) 
f.close()

次に、ファイルを移動し、dbBに接続したら次の手順を実行します。

import pickle 
records_a = pickle.load(open('pickled.records_a.txt'))
for r in records_a:
    r.id = None
    r.save()

お役に立てれば

于 2011-01-10T11:13:04.440 に答える
1

その場合、キーとして GUID を使用する必要があります。データベースはこれらを自動的に生成できます。Google固有識別子. 50 以上のウェアハウスがすべてリモートでデータを挿入し、SQL Server レプリケーションを使用してデータをプライマリ データベースに送信しています。これは一意であることが保証されているため、それらはすべて主キーとして GUID を使用します。それは非常にうまく機能します。

于 2010-12-21T10:03:18.800 に答える
0

models.Model クラスを拡張してカスタム ベース モデルを作成し、その中に汎用マネージャーを記述します。次に、カスタム .save() メソッドでモデルを編集して、カスタム ベース モデルを拡張します。これは、いくつかの古い行を更新する場合を除いて、db テーブル構造にも古い保存データにも影響しません。古いデータがある場合は、すべての記録を偽の更新にします。

于 2011-01-07T13:58:22.517 に答える