직접 전송 가져오기에 새로운 관계 추가하기
전반적으로 직접 전송 가져오기에 새로운 관계를 추가하려면 다음을 수행해야 합니다:
- 내보낸 데이터 디렉터리에 새 관계 추가.
- 데이터 처리 지시 사항이 있는 가져오기 단계에 새 ETL(추출/변환/로드) 파이프라인 추가.
- 새로 만든 파이프라인을 가져오기 단계 디렉터리에 추가.
- 충분한 테스트 커버리지 보장.
원본에서 내보내기
우리가 내보내는 몇 가지 관계 유형이 있습니다:
- ActiveRecord 연결.
import_export.yml
파일에서 읽은 후 JSON으로 직렬화하여 NDJSON 파일에 기록됩니다. 각 관계는.gz
파일에 내보내어집니다. 컬렉션의 경우.tar.gz
파일로 업로드되어 GitLab 대상 인스턴스의 REST API를 사용하여 내보내고 가져오기 위해 서비스됩니다. - 바이너리 파일. 예를 들어, 업로드나 LFS 객체.
- 내보내지는 관계는 아니지만 가져오는 동안 GraphQL API에서 직접 읽히는 소수의 관계.
ActiveRecord 연결의 경우 성능상의 이유로 NDJSON 대신 GraphQL API를 사용해야 합니다. 많은 중첩된 연결은 많은 네트워크 요청을 생성할 수 있으므로 전체 마이그레이션을 느리게 만들 수 있습니다.
ActiveRecord 관계 내보내기
직접 전송 가져오기의 기본 동작은 파일 기반 가져오기를 많이 기반으로 하며, 이는 내보내기에 포함될 Project
연결 디렉터리을 설명하는 import_export.yml
파일을 사용합니다. Group
에 대한 유사한 import_export.yml
도 사용할 수 있습니다.
예를 들어 새로운 Project
연결인 documents
가 있다고 가정해 봅시다. 이 새로운 연결을 가져오기를 지원하려면 다음을 해야 합니다:
-
import_export.yml
파일에 추가. - 새 관계에 대한 테스트 커버리지 추가.
- 추가한 연결이 기대대로 내보내는지 확인.
import_export.yml
파일에 추가
-
import_export.yml
의tree.project
에 연결을 추가합니다.diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml index 43d66e0e67b7..0880a27dfce2 100644 --- a/lib/gitlab/import_export/project/import_export.yml +++ b/lib/gitlab/import_export/project/import_export.yml @@ -122,6 +122,7 @@ tree: - label: - :priorities - :service_desk_setting + - :documents group_members: - :user
연결이 기업용 전용 기능과 관련이 있다면 파일 끝에 해당 기업용 파일에만 내보내고 가져오도록하기 위해ee.tree.project
트리에 추가합니다.연결에 하위 관계를 포함할 필요가 없는 경우 여기까지입니다. 그러나 더 많은 하위 관계가 필요한 경우(예: 노트), 해당 관계를 나열해야 합니다. documents에서 award emojis(노트의 어워드 이모지 포함) 및 award emojis(문서의 어워드 이모지 포함)가 있을 수 있다고 가정해 봅시다. 이 경우 우리의 관계는 다음과 같습니다:
diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml index 43d66e0e67b7..0880a27dfce2 100644 --- a/lib/gitlab/import_export/project/import_export.yml +++ b/lib/gitlab/import_export/project/import_export.yml @@ -122,6 +122,7 @@ tree: - label: - :priorities - :service_desk_setting + - documents: - :award_emoji - notes: - :award_emoji group_members: - :user
-
관계의
included_attributes
를 추가합니다. 기본적으로 YAML 파일의included_attributes
디렉터리에 나열되지 않은 관계 속성은 내보내기와 가져오기 양쪽에서 필터링됩니다. 필요한 속성을 포함하려면 다음과 같이 디렉터리에 추가해야 합니다:diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml index 43d66e0e67b7..dbf0e1275ecf 100644 --- a/lib/gitlab/import_export/project/import_export.yml +++ b/lib/gitlab/import_export/project/import_export.yml @@ -142,6 +142,9 @@ import_only_tree: # Only include the following attributes for the models specified. included_attributes: + documents: + - :title + - :description user: - :id - :public_email
-
관계의
excluded_attributes
도 추가합니다. 파일에excluded_attributes
디렉터리도 있습니다.Project
에는 제외된 속성을 추가할 필요는 없지만,Group
에 대해서는 해야 합니다. 이 디렉터리은 내보내기에 포함되어서는 안 되며 가져오기시 무시할 속성을 나타냅니다. 이러한 속성들은 보통 다음과 같습니다:-
_id
나_ids
로 끝나는 것 -
attributes
를 포함하는 것(단,custom_attributes
제외) -
_html
로 끝나는 것 - 민감한 내용(예: 토큰, 암호화된 데이터)
여기에서 금지된 참조의 전체 디렉터리을 확인하세요.
-
-
관계의
methods
추가합니다. 만약 관계에document.signature
와 같은 메소드가 있는 경우라면,methods
섹션에 추가할 수 있습니다. 내보낸 값은 내보내기에 있고 가져오기시에 무언가를 할 수 있습니다. 예를 들어, 필드에 할당할 수 있습니다.
예를 들어, note_diff_file.diff_export
메소드의 반환 값을 내보냈으며 내보낸 값을 가져 올 때 note_diff_file.diff
에 설정합니다.
새 관계에 대한 테스트 커버리지 추가
직접 전송은 내부적으로 파일 기반 가져오기를 사용하기 때문에, 파일 기반 가져오기의 범위에서 테스트 커버리지를 추가해야 합니다. 또한 직접 전송 가져오기의 내보내기 부분도 커버해야 하므로 새 관계에 대한 테스트를 추가해야 합니다.
-
spec/lib/gitlab/import_export/project/tree_saver_spec.rb
에 테스트를 추가합니다.Group
에 대한 유사한 파일도 있습니다. - 기업용 관계에 대한 경우
ee/spec/lib/ee/gitlab/import_export/project/tree_saver_spec.rb
을 확인합니다.
새로운 테스트를 추가하기 위해 다른 관계 예시를 따릅니다.
추가된 관계가 기대대로 내보내는지 확인
import_export.yml
에 지정된 새로 추가된 관계는 자동적으로 디스크에 기록된 내보내기 파일에 추가되므로 추가 조치가 필요하지 않습니다.
관계가 추가되고 테스트도 추가되면 관계가 내보내는 것을 매뉴얼으로 확인할 수 있습니다. 관계는 자동으로 다음 두 곳에 모두 포함되어야 합니다:
- 파일 기반 가져오기 및 내보내기. 프로젝트 내보내기 기능을 사용하여 내보내고 내보낸 데이터를 다운로드하여 확인합니다.
- 직접 전송 내보내기.
export_relations
API를 사용하여 내보내고 내보낸 관계를 다운로드하여 확인합니다(일괄적으로 내보낼 수 있습니다).
이진 관계 내보내기
이진 관계를 지원하려면:
- 디스크에서 내보내기를 수행하는 새로운 내보내기 서비스를 생성합니다. 예시는
BulkImports::LfsObjectsExportService
를 참조하세요. -
list of
file_relations
에 관계를 추가합니다. - 관계를
BulkImports::FileExportService
에 추가합니다.
대상지에서 가져오기
앞서 언급했듯이, 직접 전송 가져오기에는 세 가지 유형의 관계가 있습니다.
-
export_relations
API에서 다운로드되는 NDJSON으로 내보낸 관계. 예를 들어,documents.ndjson.gz
입니다. - GraphQL API 관계. 예를 들어
members
정보는 GraphQL을 사용하여 그룹 및 프로젝트 사용자 멤버십을 가져옵니다. -
export_relations
API에서 다운로드되는 이진 관계. 예를 들어,lfs_objects.tar.gz
입니다.
직접 전송 가져오기 프로그램은 Extract/Transform/Load 데이터 처리 기술에 기반하므로, 관계를 가져오기 시작하려면 다음을 정의해야 합니다:
- 새 관계 가져오기 파이프라인. 예를 들어,
DocumentsPipeline
. - 파이프라인이 데이터를 추출하는 데 사용하는 데이터 추출기. 예를 들어,
NdjsonPipeline
. - 데이터를 필요한 형식으로 변환하는 일련의 클래스인 변환기 디렉터리.
- 데이터를 어딘가에 영구적으로 저장할 수 있는 로더. 예를 들어, 데이터베이스의 행을 저장하거나 새로운 LFS 객체를 생성하는 등.
가져오는 관계의 유형에 상관없이 파이프라인 클래스 구조는 동일합니다:
module BulkImports
module Common
module Pipelines
class DocumentsPipeline
include Pipeline
def extract(context)
BulkImports::Pipeline::ExtractedData.new(data: file_paths)
end
def transform(context, object)
...
end
def load(context, object)
document.save!
end
end
end
end
end
NDJSON에서 관계 가져오기
파이프라인 정의
이전 예제에서, 우리의 documents
관계는 NDJSON 파일로 내보내어집니다. 이 경우, 다음을 모두 사용할 수 있습니다:
-
NdjsonPipeline
은 JSON에서 ActiveRecord 객체로의 자동 데이터 변환(내부적으로 파일 기반의 가져오기를 사용함)을 포함합니다. -
NdjsonExtractor
는/export_relations/download
REST API 엔드포인트를 사용하여 소스 인스턴스에서.ndjson.gz
파일을 다운로드합니다.
ETL 파이프라인의 각 단계는 메서드 또는 클래스로 정의할 수 있습니다.
class DocumentsPipeline
include NdjsonPipeline
relation_name 'documents'
extractor ::BulkImports::Common::Extractors::NdjsonExtractor, relation: relation
end
이 새 파이프라인은 이제 다음 작업을 수행합니다:
- 소스 인스턴스에서
documents.ndjson.gz
파일을 다운로드합니다. - NDJSON 파일의 내용을 읽고 JSON을 역직렬화하여 ActiveRecord 객체로 변환합니다.
- 프로젝트 범위 내에서 데이터베이스에 저장합니다.
파이프라인은 다음 중 하나의 하위에 배치될 수 있습니다:
- 공유되고 그룹 및 프로젝트 마이그레이션 모두에서 사용되는 경우
BulkImports::Common::Pipelines
네임스페이스. 예를 들어,LabelsPipeline
은 공통 파이프라인이며 그룹 및 프로젝트 단계 디렉터리에서 모두 참조됩니다. - 프로젝트 마이그레이션에 속하는 경우
BulkImports::Projects::Pipelines
네임스페이스. - 그룹 마이그레이션에 속하는 경우
BulkImports::Groups::Pipelines
네임스페이스.
새 파이프라인을 단계에 추가
직접 전송 가져오기 프로그램은 그룹 및 프로젝트를 단계별로 마이그레이션 실행합니다. 각 단계는 다음 단계로 이동하기 전에 완전히 완료되어야 합니다.
프로젝트
단계에 파이프라인을 추가해 봅시다:
module BulkImports
module Projects
class Stage < ::BulkImports::Stage
private
def config
{
project: {
pipeline: BulkImports::Projects::Pipelines::ProjectPipeline,
stage: 0
},
repository: {
pipeline: BulkImports::Projects::Pipelines::RepositoryPipeline,
maximum_source_version: '15.0.0',
stage: 1
},
documents: {
pipeline: BulkImports::Projects::Pipelines::DocumentsPipeline,
minimum_source_version: '16.11.0',
stage: 2
}
end
end
end
end
다음을 명시했습니다:
-
stage: 2
, 따라서 프로젝트 및 리포지터리 단계가 먼저 완료되어야 우리의 파이프라인이 2단계에서 실행됩니다. -
minimum_source_version: '16.11.0'
. 이번 마일스톤에서documents
관계를 내보내기하기 시작했으므로 이것은 이전 GitLab 버전에서는 사용할 수 없습니다. 따라서 원본 버전이 16.11 이상일 때만이 파이프라인이 실행됩니다.
maximum_source_version
속성을 지정할 수 있습니다.파이프라인을 테스트로 커버하기
이미 내보내기 부분을 테스트했기 때문에 가져오기 부분도 동일하게 해야 합니다. 직접 전송 가져오기 프로그램에는 각 파이프라인마다 별도의 스펙 파일이 있어야 합니다. 구체적인 예시는 이 예시처럼 보일 것입니다.
GraphQL API에서 관계 가져오기
관계가 GraphQL API를 통해 사용 가능한 경우, GraphQlExtractor
를 사용하여 파이프라인 클래스 내에서 변환 및 로드를 수행할 수 있습니다.
MembersPipeline
예시:
module BulkImports
module Common
module Pipelines
class MembersPipeline
include Pipeline
transformer Common::Transformers::ProhibitedAttributesTransformer
transformer Common::Transformers::MemberAttributesTransformer
def extract(context)
graphql_extractor.extract(context)
end
def load(_context, data)
...
member.save!
end
private
def graphql_extractor
@graphql_extractor ||= BulkImports::Common::Extractors::GraphqlExtractor
.new(query: BulkImports::Common::Graphql::GetMembersQuery)
end
end
end
end
end
나머지 단계는 위의 단계와 동일합니다.
이진 관계 가져오기
이진 관계 파이프라인은 다른 파이프라인과 동일한 구조를 가지며, 추출/변환/로드 단계에서 무슨 일이 발생하는지 정의하면 됩니다.
LfsObjectsPipeline
예시:
module BulkImports
module Common
module Pipelines
class LfsObjectsPipeline
include Pipeline
file_extraction_pipeline!
def extract(_context)
download_service.execute
decompression_service.execute
extraction_service.execute
...
end
def load(_context, file_path)
...
lfs_object.save!
end
end
end
end
end
데이터 다운로드를 돕는 여러 유용한 서비스 클래스가 있습니다:
-
BulkImports::FileDownloadService
: 주어진 위치에서 파일을 다운로드합니다. -
BulkImports::FileDecompressionService
: 필요한 유효성 검사가 포함된 Gzip 압축 해제 서비스. -
BulkImports::ArchiveExtractionService
: Tar 압축 해제 서비스입니다.