データベース A のデータの一部をシリアライズし、データベース B でデシリアライズする方法 (異なるインストール間での一種の保存/復元) を研究しており、ID の重複による問題を回避するために Djangoの自然キーを調べました。 .
唯一の問題は、カスタム マネージャーと新しいメソッドをすべてのモデルに追加する必要があることです。unique=True
またはunique_togheter
フィールドを見て、Djangoに自然キーを自動的に生成させる方法はありますか?
データベース A のデータの一部をシリアライズし、データベース B でデシリアライズする方法 (異なるインストール間での一種の保存/復元) を研究しており、ID の重複による問題を回避するために Djangoの自然キーを調べました。 .
唯一の問題は、カスタム マネージャーと新しいメソッドをすべてのモデルに追加する必要があることです。unique=True
またはunique_togheter
フィールドを見て、Djangoに自然キーを自動的に生成させる方法はありますか?
この回答は 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
私の解決策は自然キーとは何の関係もありませんが、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()
お役に立てれば
その場合、キーとして GUID を使用する必要があります。データベースはこれらを自動的に生成できます。Google固有識別子. 50 以上のウェアハウスがすべてリモートでデータを挿入し、SQL Server レプリケーションを使用してデータをプライマリ データベースに送信しています。これは一意であることが保証されているため、それらはすべて主キーとして GUID を使用します。それは非常にうまく機能します。
models.Model クラスを拡張してカスタム ベース モデルを作成し、その中に汎用マネージャーを記述します。次に、カスタム .save() メソッドでモデルを編集して、カスタム ベース モデルを拡張します。これは、いくつかの古い行を更新する場合を除いて、db テーブル構造にも古い保存データにも影響しません。古いデータがある場合は、すべての記録を偽の更新にします。