feat(exporter): Prisma ORM exporter 추가#151
Conversation
| id Int @id | ||
| val Int @default(dbgenerated("nextval('my_seq')")) | ||
|
|
||
| @@map("items") |
There was a problem hiding this comment.
차음부터 model Items로 쓰는 방식을 어떨까요?
There was a problem hiding this comment.
복수형 → 단수형 변환 로직은 제거했습니다.
일반적으로 DB는 snake_case, Prisma는 PascalCase를 사용하는데,
이 부분도 통일해서 @@Map() 사용을 없애는 방향이 좋을까요?
c5da111 to
e30d125
Compare
Add a Prisma schema generator as a fourth ORM backend alongside SeaORM, SQLAlchemy, and SQLModel. Renders enum + model blocks with full schema context (relations, indexes, unique/composite constraints, native types, default attributes, referential actions) and wires Prisma into the cross-ORM test harness and CLI export command. Model names use plural PascalCase; string default values escape backslashes correctly. Snapshots cover the full column-type matrix plus relation, enum, default, and reserved-identifier scenarios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generate the 60 missing Prisma insta snapshots so the Prisma backend is cross-compared with the other four ORMs through the shared orm_cases! matrix. The Orm::Prisma cases were already wired into every test; only the accepted snapshot files were absent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4a9c0d2 to
88bde9e
Compare
Mirrors the sqlmodel/sqlalchemy 4-file convention. mod.rs is now a thin orchestrator; render.rs holds model rendering and relation logic; types.rs holds column-type mapping; enums.rs holds enum rendering and naming helpers. Public API surface (PrismaExporter, PrismaExporterWithConfig, export, render_entity, render_entity_with_schema, to_pascal_case_for_tests) unchanged. All 565 tests pass with byte-identical snapshot output. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…, relation field naming - @@unique/@@index DB constraint names now emit `map:` instead of `name:` (`name:` on @@index is invalid in Prisma 2.30+; on @@unique it sets the Prisma Client accessor, not the DB constraint name) - integer-backed enum @default(...) now resolves to a variant identifier via numeric-value or variant-name match (e.g. @default(COMPLETED)), falling back to dbgenerated() when unmatched, instead of emitting an invalid bare int - inline FK relation field gets a `_rel` suffix when stripping `_id` would collide with the scalar column; self-referential back-relation is emitted - regenerate affected Prisma snapshots Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@owjs3901 리뷰 감사합니다. 지적해주신 부분 모두 반영했습니다:
네이밍 관련해서 PascalCase + |
|
@yyuneu snapshot이 업데이트 되지 않은 것 같습니다 |
해당 코드 관련 해서 테스트 코드 삽입 했고, 아웃풋도 스냅샷이랑 동일히게 코드 작성 끝났다고 하는데, 혹시 다른 부분이 있어서 스냅샷이 반영 안된 것 같다고 하신건가요? 다른 모듈에서 사이드 이펙트나, 스냅샷 갱신이 누락된 부분이 있는건가요? 확인하진 부분 구체적인 포인트 조금만 더 알려주시면 빠르게 파악해서 반영 하겠습니다. |
|
죄송합니다, 제가 과거 커밋을 본것 같습니다. clientOutput 옵션의 경우 이미
감사합니다. |
개요
5번째 ORM 백엔드로 Prisma를 추가합니다 (기존: SeaORM / SQLAlchemy / SQLModel / JPA).
TableDef스키마를 datasource, generator, enum 블록(전역 dedup), model 블록을포함한 단일
schema.prisma파일로 변환합니다.실행:
vespertide export --orm prisma설계상 특이사항
1. 왜 Prisma만 별도 config (
PrismaConfig)를 가지는가Prisma는 단일 스키마 언어입니다.
datasource db { provider, url, relationMode }와generator client { provider, output }이 모델과 같은 파일 안에 있어야 합니다.나머지 ORM 백엔드(SeaORM / SQLAlchemy / SQLModel / JPA)는 모델 단위 코드만
생성하므로 이런 메타 정보가 필요 없습니다. 즉, Prisma만 "모델 외 입력"(provider,
client output 경로, relation mode)을 받아야 하기 때문에
vespertide-config에PrismaConfig를 새로 추가했습니다. 필드 세 개(provider / client_output /relation_mode)와 postgresql 기본값을 가집니다.
2. 왜
export.rs에if matches!(orm, OrmArg::Prisma) { return cmd_export_prisma(...) }분기가 있는가기존 export 파이프라인은 모델 N개 → 파일 N개 전제입니다:
walk_models→ 모델별render_entity_with_schema→ 파일별 write → mod chain.Prisma는 모델 N개 → 파일 1개이며 위 파이프라인이 만족시킬 수 없는 두 가지
요구가 있습니다:
블록은 파일에 한 번만 등장해야 함)
그래서
cmd_export가 진입 즉시cmd_export_prisma로 분기하고,PrismaExporterWithConfig::render_schema(&all_tables)에서 스키마 전체를 한 번에조립합니다.
Orm::Prisma는 인터페이스 일관성 + 분기 안 자체 clean 호출을 위해clean_export_dir/build_output_path에prisma확장자로 함께 등록만 해두었습니다.
테스트 설계
명세는
crates/vespertide-exporter/src/prisma/TESTING.md에 있습니다. 3-layer 구조:render_entity(table)로 검증.render_entity_with_schema(table, schema)로 검증.TableConstraint::ForeignKey가하나라도 있는
TableDef는 무조건 Layer 2.설계 규칙:
insta::assert_snapshot!사용.assert!(result.contains(...))방식은 금지 — 회귀 감지 정확도 확보 및 출력 전체를 고정.
singularize 등)는
#[rstest]파라미터화로 작성.ColumnDef생성은 로컬 헬퍼(col,col_null,col_with_default,col_with_comment,pk,uniq,idx,fk,table,render_schema_all)로분리하여 케이스 본문을 짧게 유지.
테스트 65개 / 스냅샷 54개가 커버하는 범위:
select,order,model, ...), 예약어 컬럼명 (default,unique, ...), description 안의 newline/quote/brace, default 값 안의 quoteTest plan
cargo build -p vespertide-exporter— 정상cargo test -p vespertide-exporter --lib prisma::— 65 passedcargo test -p vespertide-exporter orm::— 207 passed (Prisma dispatch 스냅샷 포함)examples/app/에cargo run -p vespertide-cli -- export --orm prisma실행해 동작 확인npx prisma format/npx prisma validate통과 여부 확인🤖 Generated with Claude Code