Conversation
This was referenced Sep 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#169 에서 GORM 백엔드 관련 변경 사항만 분리한 PR입니다. Django는 #198 로, 랜딩 페이지는 #199 로 각각 분리하여 올립니다. 기존 #169 는 이 세 PR로 대체하고 닫을 예정입니다.
작업은 @2heunxun 님이 시작하셨으며, 중간부터 제가 이어받았습니다. 첫 커밋은 해당 작성자의 GORM 구현을 upstream과 병합한 상태 그대로입니다.
#169의 리뷰 코멘트와 답변은 기존 PR에 남아 있으며, 이 PR의 범위에 해당하는 내용은 아래에 다시 정리했습니다.
#169 리뷰 반영
SimpleColumnType과ReferenceAction의#[non_exhaustive]를 제거하고, 미러 enum인SimpleColumnKind와ReferenceActionKind를 삭제했습니다. 이에 따라 불필요해진 와일드카드 arm 12곳(query 3, exporter 8, planner 1)도 제거했습니다.schemas/의 JSON Schema는 description만 재생성되었습니다. 0.x 기준 breaking change이므로 changepack에 기재했습니다.ComplexColumnType은 변경 범위를 넓히지 않기 위해 그대로 두었습니다. 같은 방향으로 정리하기를 원하시면 함께 처리하겠습니다.gorm설정 섹션을 제거했습니다. 패키지명은 export 디렉터리의 마지막 경로 요소에서만 결정되며, 해당 추론 로직은 config가 아닌 exporter 내부(GormExporterWithConfig::for_export_dir)에 배치했습니다. Go 식별자로 사용할 수 없는 이름은 유효한 식별자로 변환하고, 변환할 수 없는 경우에만models를 사용합니다.#[cfg(test)] mod tests내부로 옮겼습니다.CLAUDE.md,CHANGELOG.md,.github,.idea, JPA 스냅샷,erd/mod.rs는 upstream과 동일하므로 diff에 포함되지 않습니다.CLI 출력
vespertide export --orm gorm은 전체 스키마를 단일models.go파일로 출력합니다.Go에서는 디렉터리가 곧 패키지이며, 관계가 양쪽에서 렌더링됩니다. 따라서 모델 디렉터리를 나누면 두 패키지가 서로를 import하는 순환 참조가 발생해 컴파일되지 않습니다.
출력 파일이 하나로 고정되어 있으므로 확장자 sweep은 수행하지 않습니다(Drizzle과 동일).
파일 첫 줄에는
Code generated by vespertide. DO NOT EDIT.를 기록하며, 이 생성 표식으로 시작하지 않는 기존models.go는 덮어쓰지 않고 에러로 알립니다.GORM 출력에서 수정한 사항
작업을 이어받은 후 생성물을
gofmt -l과go vet(실제gorm.io/gorm의존)에 넣어 검증하는 과정에서 컴파일 오류를 일으키는 출력들을 확인했습니다.수정한 내용은 다음과 같습니다.
1users→X1users), 구조체의TableName()메서드와 이름이 겹치는 필드, 값 타입 belongs-to로 인한 재귀 타입(항상 포인터로 처리), enum 타입·상수의 중복 선언references:누락, 복합 FK의 역방향 관계 누락, one-to-one이 has-many로 출력되던 문제(unique FK 및 FK 자체가 해당 테이블의 PK인 경우)char(N)과 네트워크 타입의type:, 기본값 태그(GORM은 문자열 필드의 기본값을 값 그대로 읽고 양끝 따옴표를 모두 제거합니다)scope_names.rs). 테이블role과 enumrole, 상수Status+code와 테이블status_code가 중복 선언되지 않습니다."·\·개행을string_literal로 이스케이프합니다. 기존 Drizzle의 헬퍼를 공용으로 옮긴 것으로, Drizzle 출력은 바이트 단위로 동일합니다.gofmt -l을 그대로 통과합니다.다른 백엔드에 영향을 주는 변경
기존 스냅샷은 변경되지 않았습니다. 새로 추가된 스냅샷 125개는 GORM 스냅샷 75개와 신규 fixture에 대한 다른 ORM 출력 50개로 구성됩니다.
Profile[]→Profile?). 기존 공용 역방향 스캔이 unique 여부만 확인하고 있던 문제를 수정했습니다. SeaORM은 기존에도 has-one으로 출력하고 있었습니다. 신규 fixture에서만 드러나는 변경이며, 기존 스냅샷은 그대로입니다.ts_string을 공용string_literal로 이동하고, 정수 enum 기본값을 값으로 변환하는integer_enum_variant_value를 Drizzle에서 공용으로 옮겼습니다.single_column_fk_targets를single_column_fk_details로 통합하고(SQLAlchemy·SQLModel 호출부),BackRelation에 FK·참조 컬럼 및 액션 필드를 추가했습니다(Prisma·Drizzle이 사용하는 필드는 그대로 유지). SeaORM의 JSONB 판정도 공용is_jsonb_custom_type으로 옮겼습니다.테스트
렌더링 결과를
contains()로 확인하던 모듈별 테스트와 모듈별 스냅샷을 공용 7-ORM 스냅샷으로 통합했습니다. 각 모듈에는 타입·기본값·이름 규칙에 대한 함수 단위 매핑 테스트만 남겼습니다.CLI에는 GORM 출력 스냅샷 2개를 추가했습니다.
orm_cases!로 검증되지 않는 CLI 배선(단일 파일 출력, 생성 표식, 패키지명)을 고정하기 위한 테스트입니다.검증
-D warnings), 전체 테스트, line-budget, schema-gen 무변경, cargo-denygo vet(실제gorm.io/gorm의존),gofmt -lexamples/app(모델 11개)과 오류가 발생하기 쉬운 입력만 모은 스키마 모두 통과. GORM 스냅샷 75개도 모두 gofmt 레이아웃과 일치현재 이 PR의 워크플로는 승인 대기(
action_required) 상태입니다. 실행을 승인해 주시면 감사하겠습니다.미리 말씀드릴 사항
scope_names.rs는 Drizzle의drizzle::bindings와 역할이 일부 겹칩니다. 다만 Drizzle은 import 심볼과 콜백 파라미터를 먼저 점유하고,customType·relationsconst까지 처리하며, enum 이름을 항상 테이블로 한정하는 등 이름 규칙이 다릅니다. 따라서 이 PR에서는 통합하지 않았습니다. 통합하는 편이 낫다고 보시면 후속 PR로 진행하겠습니다.이 PR에서 다루지 않은 사항
작업 중 확인한 upstream의 기존 동작 관련 결함입니다. 다른 백엔드나 크레이트까지 수정해야 하는 내용이므로 이번 PR에서는 다루지 않았습니다.
아래 표의 첫 세 건은 실제 사용에 미치는 영향이 큰 문제입니다.
schema.prisma가 삭제됩니다. Drizzle과 이 PR의 GORM은 sweep을 수행하지 않습니다.DeclarativeBase를 직접 상속하여 SQLAlchemy 2.0에서InvalidRequestError가 발생합니다. 모든 모델에 해당하며, 파일 간relationship참조를 위한 공용Base와__init__.py도 없습니다.json컬럼의default를{"a": 1}로 지정하면 SQL 계층에서DEFAULT {"a": 1}을 그대로 출력하여 DDL이 실패합니다(SQLite에서 확인).'{"a": 1}'처럼 SQL 리터럴로 출력해야 합니다. exporter fixture의json_default도 전자의 형태입니다.package선언 누락package선언이 없어 컴파일되지 않습니다.user_id와userId가 한 테이블에 있으면 SeaORM·JPA·Drizzle에서 동일한 필드가 두 번 선언됩니다. GORM은 공용claim_binding으로 접미사를 붙여 처리합니다.mapped_column("JSONB", …)로 렌더링되어 타입이 아닌, 이름이"JSONB"인 컬럼이 선언됩니다."·\가 포함되거나 이름이1st·info-level이면 문법 오류가 발생합니다.1st-users.json) import할 수 없는 모듈 파일이 생성됩니다. #169에서는 수정했으나 이 PR의 주제와 무관하여 제외했습니다.cmd_export가validate_schema를 거치지 않음collect_model_paths가read_dir순서를 그대로 사용하므로, 동일한 식별자로 변환되는 테이블의 번호가 환경에 따라 달라질 수 있습니다.pluralize사본, 별도의 역방향 관계 스캔, 동작이 다른primary_key_columns가 남아 있습니다.--export-dir도움말modelsDir로 안내하지만 실제 값은modelExportDir이며, 파일이 삭제될 수 있다는 안내도 없습니다.build_output_path의 마지막 arm은 도달할 수 없지만 테스트 2개가 이를 고정하고 있으며,tests/prisma.rs는 생성 파일을contains()로 확인합니다.