일괄 백그라운드 마이그레이션 스펙 헬퍼
일괄 백그라운드 마이그레이션을 위한 버전 관리된 스펙 헬퍼 라이브러리는 마이그레이션 스펙의 반복 코드를 줄여줍니다. 일괄 백그라운드 마이그레이션 스펙에서는 종종 MigrationsHelpers의 table() 메서드를 사용하여 여러 테이블 헬퍼를 정의해야 합니다.
일괄 백그라운드 마이그레이션을 위한 버전 관리된 스펙 헬퍼 라이브러리는 마이그레이션 스펙의 반복 코드를 줄여줍니다.
스펙 헬퍼 기능#
일괄 백그라운드 마이그레이션 스펙에서는 종종 MigrationsHelpers의 table() 메서드를 사용하여
여러 테이블 헬퍼를 정의해야 합니다. 이로 인해 반복적인 코드가 발생합니다:
# 헬퍼 없음 - 반복적
RSpec.describe Gitlab::BackgroundMigration::BackfillProjectId do
let!(:projects) { table(:projects) }
let!(:issues) { table(:issues) }
let!(:notes) { table(:notes) }
let!(:users) { table(:users) }
# ... 더 많은 테이블 정의
end
일괄 백그라운드 마이그레이션 스펙 헬퍼는 지연 평가와 메모이제이션을 통해 이러한 반복을 제거합니다:
# 헬퍼 사용 - 간결하고 깔끔
RSpec.describe Gitlab::BackgroundMigration::BackfillProjectId do
include Gitlab::BackgroundMigration::SpecHelpers::V1
# 필요한 테이블 선언
tables :projects, :issues, :notes, :users
end
버전 관리#
헬퍼는 하위 호환성을 보장하기 위해 버전 관리됩니다. 수정이 필요한 경우, 기존 스펙을 깨뜨리지 않고 새 버전을 만들 수 있습니다.
사용 가능한 버전#
- V1: 테이블 헬퍼가 있는 초기 버전 (현재)
특정 버전 사용#
사용하려는 버전 모듈을 포함합니다:
RSpec.describe Gitlab::BackgroundMigration::SomeMigration do
include Gitlab::BackgroundMigration::SpecHelpers::V1
end
기능#
명시적 테이블 선언#
테이블에 접근하기 전에 tables 메서드를 사용하여 명시적으로 선언해야 합니다:
RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceId do
include Gitlab::BackgroundMigration::SpecHelpers::V1
# 스펙에 필요한 모든 테이블 선언
tables :issues, :namespaces, :projects
it 'backfills namespace_id' do
# 선언 후 처음 접근 시 테이블이 생성됩니다
namespace = namespaces.create!(name: 'test', path: 'test')
project = projects.create!(namespace_id: namespace.id)
issue = issues.create!(project_id: project.id)
end
end
메모이제이션#
테이블 헬퍼는 메모이제이션되므로, 반복 접근 시 동일한 인스턴스를 반환합니다:
RSpec.describe Gitlab::BackgroundMigration::SomeMigration do
include Gitlab::BackgroundMigration::SpecHelpers::V1
tables :users
it 'uses memoized tables' do
users_1 = users # 처음 접근 시 헬퍼를 생성합니다
users_2 = users # 동일한 인스턴스를 반환합니다
expect(users_1).to be(users_2)
end
end
커스텀 구성#
커스텀 옵션으로 테이블을 구성할 수 있습니다:
커스텀 기본 키#
RSpec.describe Gitlab::BackgroundMigration::SomeMigration do
include Gitlab::BackgroundMigration::SpecHelpers::V1
tables :custom_table
configure_table :custom_table, primary_key: :custom_id
it 'uses custom primary key' do
record = custom_table.create!(custom_id: 1, name: 'test')
expect(custom_table.primary_key).to eq('custom_id')
end
end
커스텀 데이터베이스#
RSpec.describe Gitlab::BackgroundMigration::SomeMigration do
include Gitlab::BackgroundMigration::SpecHelpers::V1
tables :ci_builds
configure_table :ci_builds, database: :ci
end
파티션된 테이블#
RSpec.describe Gitlab::BackgroundMigration::SomeMigration, migration: :gitlab_ci do
include Gitlab::BackgroundMigration::SpecHelpers::V1
tables :p_ci_builds
configure_table :p_ci_builds, partitioned: true, database: :ci
it 'works with partitioned tables' do
build = p_ci_builds.create!(partition_id: 100, project_id: 1)
end
end
마이그레이션 가이드#
기존 스펙 변환#
기존 스펙을 헬퍼를 사용하도록 변환하려면:
이전:
RSpec.describe Gitlab::BackgroundMigration::BackfillProjectId,
feature_category: :code_review_workflow do
let!(:projects) { table(:projects) }
let!(:merge_requests) { table(:merge_requests) }
let!(:approval_rules) { table(:approval_merge_request_rules) }
it 'backfills project_id' do
project = projects.create!(name: 'test')
mr = merge_requests.create!(target_project_id: project.id)
rule = approval_rules.create!(merge_request_id: mr.id)
# 테스트 로직
end
end
이후:
RSpec.describe Gitlab::BackgroundMigration::BackfillProjectId,
feature_category: :code_review_workflow do
include Gitlab::BackgroundMigration::SpecHelpers::V1
tables :approval_merge_request_rules, :merge_requests, :projects
it 'backfills project_id' do
project = projects.create!(name: 'test')
mr = merge_requests.create!(target_project_id: project.id)
rule = approval_merge_request_rules.create!(merge_request_id: mr.id)
# 테스트 로직
end
end
사용 시기#
헬퍼를 사용해야 할 때:
- 새 일괄 백그라운드 마이그레이션 스펙을 작성할 때
- 여러 테이블 헬퍼가 필요할 때
- 반복 코드를 줄이고 싶을 때
수동 정의를 고려해야 할 때:
- 특정 테이블 구성이 필요할 때
- 복잡한 커스텀 테이블 설정으로 작업할 때
- 스펙에서 하나 또는 두 개의 테이블만 사용할 때
모범 사례#
- 항상 테이블을 명시적으로 선언 -
tables메서드를 사용하여 스펙에 필요한 모든 테이블을 선언합니다. 테이블은 자동으로 사용 가능하지 않으며 사용 전에 선언해야 합니다. - 테이블을 알파벳 순서로 선언 - 이렇게 하면 스펙 전반의 일관성과 가독성이 향상됩니다.
- 최신 버전 사용 - 특별한 이유가 없는 한 새 스펙에는 V1(또는 최신 버전)을 사용합니다.
- 선언 후 구성 - 먼저
tables로 테이블을 선언한 다음 필요한 경우configure_table로 구성합니다. - 접근 방식을 혼용하지 않음 - 스펙 헬퍼 또는 수동
let!정의 중 하나를 사용하고, 동일한 스펙에서 둘 다 사용하지 않습니다. - 구성을 최소화 - 커스텀 옵션(기본 키, 데이터베이스, 파티셔닝)이 필요한 경우에만 테이블을 구성합니다.
문제 해결#
테이블을 찾을 수 없음#
"table not found" 오류가 발생하면 다음을 확인합니다:
- 클래스 수준에서
tables :table_name을 사용하여 테이블을 선언했는지 - 스펙에 지정된 스키마 버전에 테이블이 존재하는지
- 올바른 데이터베이스(
:main,:ci등)를 사용하고 있는지 - 마이그레이션 메타데이터가 올바르게 설정되어 있는지
기본 키 문제#
기본 키 오류가 있는 경우:
- 테이블이 커스텀 기본 키를 사용하는지 확인합니다
- 명시적으로 구성합니다:
configure_table :table_name, primary_key: :custom_id
파티션된 테이블 문제#
파티션된 테이블의 경우:
- 올바른 마이그레이션 유형으로 스펙을 표시했는지 확인합니다:
migration: :gitlab_ci - 테이블을 파티션된 것으로 구성합니다:
configure_table :p_ci_builds, partitioned: true - 필요한 경우 데이터베이스를 지정합니다:
database: :ci
향후 버전#
새 버전이 릴리스될 때 이 문서는 다음 내용으로 업데이트됩니다:
- 이전 버전에서의 마이그레이션 가이드
- 각 버전의 새 기능
- Deprecated 공지
