병합 할 Django-ORM 관리 데이터베이스가 2 개 있습니다. 둘 다 매우 유사한 스키마를 가지고 있으며, 둘 다 auth_users뿐만 아니라 서로를 참조하는 몇 가지 다른 공유 테이블과 함께 표준 auth_users 테이블을 가지고 있습니다. 이것은 하나의 데이터베이스에 자동으로 병합하고 싶습니다.임의로 장고 모델을 자동으로 병합합니다.
이 키는 외래 키 관계 및 각 테이블의 "고유 한"레코드를 구성하는 요소에 따라 매우 간단 할 수 있습니다.
이 병합 작업을 수행 할 도구가 있는지 아는 사람 있습니까?
현재 이와 같은 것이 없으면 표준 loaddata 명령을 기반으로 내 자신의 관리 명령을 작성하려고합니다. 근본적으로 표준 dumpdata 명령을 사용하여 원본 데이터베이스에서 테이블을 내 보낸 다음 수정 된 버전의 loaddata를 사용하여 대상 데이터베이스로 "병합"합니다. 나는 데이터베이스 A와 B가 있고, 나는 데이터베이스 A를로 데이터베이스 B를 병합 할 경우
예를 들어, 나는 의사 코드에 따라 절차를 수행 할 것 :
merge_database_dst = A
merge_database_src = B
for table in sorted(merge_database_dst.get_redundant_tables(merge_database_src), key=acyclic_dependency):
key = table.get_unique_column_key()
src_id_to_dst_id = {}
for record_src in merge_database_src.table.objects.all():
src_key_value = record_src.get_key_value(key)
try:
record_dst = merge_database_dst.table.objects.get(key)
dst_key_value = record_dst.get_key_value(key)
except merge_database_dst.table.DoesNotExist:
record_dst = merge_database_dst.table(**[(k,convert_fk(v)) for k,v in record_src._meta.fields])
record_dst.save()
dst_key_value = record_dst.get_key_value(key)
src_id_to_dst_id[(table,record_src.id)] = record_dst.id
convert_fk() 함수는 src_id_to_dst_id 인덱스를 사용하여 소스 테이블의 외래 키 참조를 대상 테이블의 해당 ID로 변환합니다.
요약하면, 알고리즘은 부모를 먼저 반복하면서 종속성 순서로 병합 할 테이블을 반복합니다. 따라서 auth_users와 mycustomprofile 테이블을 병합하려면 auth_users에 종속적인데, 'auth_users', 'mycustomprofile']을 반복합니다.
각 병합 된 테이블에는 보편적으로 고유 한 레코드 (즉, "키")를 나타내는 열의 조합을 나타내는 일종의 표시기가 필요합니다. auth_users의 경우 "username"및/또는 "email"열일 수 있습니다.
데이터베이스 B의 키 값이 A에 이미있는 경우 레코드는 B에서 가져 오지 않지만 A의 기존 레코드 ID는 기록됩니다.
데이터베이스 B의 키 값이 A에 없으면 B에서 레코드를 가져오고 새 레코드의 ID를 기록합니다.
이전에 기록 된 ID를 사용하여 B의 특정 레코드에 대한 외래 키 참조를 A의 새로운 병합/기존 레코드에 매핑하는 방법을 설명하는 매핑이 만들어집니다. 향후 레코드가 A로 병합 될 때이 매핑은 외래 키를 변환하는 데 사용됩니다.
임포트 된 레코드가 dumpdata에 포함되지 않은 테이블을 참조하는 일부 경우를 상상할 수 있습니다. 이로 인해 전체 가져 오기가 실패 할 수 있으므로 가져 오기를 시뮬레이트하여 모든 항목을 보장하려면 일종의 "dryrun"옵션이 필요합니다. FK 참조는 번역 될 수 있습니다.
실용적인 접근 방법 인 것 같습니까? 더 좋은 방법이 있습니까?
편집 : 이것은 내가 찾고있는 것이 아니지만 다른 사람들이 흥미로울 것이라고 생각했습니다. Turbion project에는 동일한 데이터베이스 내의 다른 Django 모델에있는 동등한 레코드간에 변경 사항을 복사하는 메커니즘이 있습니다. 두 장고 모델 사이에 번역 레이어 (예 : merging.ModelLayer)를 정의하여 작동하므로 사용자 [email protected]의 프로필에서 "www"필드를 업데이트하면 사용자의 "url"필드가 자동으로 업데이트됩니다 [email protected]의 otherprofile.
내가 찾고있는 기능은 약간 다르다. 드문 경우지만 전체 (또는 부분) 데이터베이스 스냅 샷을 병합하려는 경우 loaddata 관리 명령의 방식과 비슷하다.
감사합니다. 내가하고 싶은 일을 정확히 이해 한 것 같습니다. 그러나 데이터 마이그레이션 기능을 병합을 수행 할 때마다 재생성해야하는 "일회성"으로 간주하기 때문에 South를 배제했습니다. – Cerin
"병합 수행"이란 의미를 이해하지 못합니다. 다른 테이블을 말하는거야? 그렇다면 맞습니다. 동일한 테이블을 병합한다는 것은 나중에 수동으로 수행하는 것보다 훨씬 쉽게 수행 할 수 있습니다 (이후 번호로 복사하거나 수행하지 않음으로써 마이그레이션을 다시 수행 할 수 있음). 나는 남한이 당신이하고있는 일을 위해 완벽하게 구축되었다고 말하는 것이 아니라, 남한과 함께이 일을 훨씬 더 쉽게 할 수 있습니다. –