ADR-0005: DB Layer: sqlc¶
Umbra 의 Go 코드에서 PostgreSQL 에 접근할 때 sqlc 로 타입 안전한 코드를 생성한다.
Status¶
Accepted
- Decided at — 2026-04-13
- Decided by — Pablo
Context¶
PostgreSQL 을 선택한 후(ADR-0004) Go 에서의 DB 접근 레이어를 결정해야 한다. 선택 기준:
- 결제 도메인의 트랜잭션 제어가 명시적
- SQL 가시성 (옵티마이저 힌트, 인덱스 활용 가능)
- 타입 안전성 (컴파일 타임에 type mismatch 감지)
- Atlas 와 책임 중복 없음
후보: sqlc, sqlx, GORM, ent.
Decision¶
sqlc 를 DB 레이어로 채택한다. 도메인별로 별도 sqlc 패키지를 생성한다.
선택 근거:
- SQL-first — 모든 쿼리가
.sql파일에 명시적. N+1 같은 의도치 않은 쿼리가 발생하지 않음 - 타입 안전 — SQL 에서 Go struct + 함수가 자동 생성되어 컴파일 타임에 mismatch 감지
- Atlas 와 책임 분리 — Atlas 는 schema 관리, sqlc 는 쿼리. AutoMigrate 중복 없음
- 결제 도메인 안전성 — 트랜잭션 제어가 명시적이라 ORM 의 자동 트랜잭션 함정 회피
- 도메인별 패키지 분리 —
db/queries/billing/→engine/billing/adapter/persistence/sqlc/로 자연 결합
Consequences¶
Positive¶
- 모든 쿼리가 코드 리뷰 대상 (SQL 그대로)
- 쿼리 성능 튜닝 가능 (인덱스, JOIN 전략 직접 작성)
- 생성된 코드가 얇아 디버깅 쉬움
- 도메인별 패키지 분리로 schema 경계 강제
Negative¶
- CRUD 쿼리를 직접 작성해야 함 (GORM 대비 보일러플레이트)
- sqlc generate 가 CI 단계로 추가됨
- 복잡한 동적 쿼리 (IN list with variable size 등) 는 별도 처리 필요
Neutral¶
- sqlc 는
.sql파일에서 코드 생성만 하므로 런타임 의존성 없음 - 생성 코드는 git commit 함 (CI 검증, 코드 리뷰 가능)
Alternatives considered¶
Alternative 1: GORM¶
Pros
- CRUD 자동 생성으로 빠른 프로토타이핑
- 연관관계 Preload 편의
Cons
- 결제 도메인 트랜잭션 위험 — 자동 생성 트랜잭션이 의도와 다르게 동작 가능
- 리플렉션 마법, 디버깅 시 실제 SQL 추적 필요
- AutoMigrate 가 Atlas 와 책임 중복
- Go 답지 않다는 비판의 대표
Why rejected — 결제 트랜잭션의 안전성이 최우선. GORM 의 자동 생성 SQL 이 의도와 불일치할 위험 허용 불가.
Alternative 2: sqlx¶
Pros
- SQL 직접 작성 (가시성 100%)
- 학습 곡선 매우 낮음
database/sql얇은 래퍼
Cons
- 타입 안전성 없음 (scan 실패는 런타임 에러)
- struct 와 SQL 의 동기화 수동
- sqlc 대비 보일러플레이트 많음
Why rejected — sqlc 가 sqlx 의 장점(SQL 명시성) + 타입 안전성 둘 다 제공. sqlc 가 상위 호환.
Alternative 3: ent¶
Pros
- 그래프 기반 스키마
- 코드 생성으로 타입 안전
Cons
- 고유 DSL 학습 부담
- PostgreSQL 고급 기능 (JSONB 조작, CTE) 지원이 ORM 계층으로 추상화
- 복잡한 쿼리는 raw SQL fallback 필요
Why rejected — 학습 부담과 SQL 추상화가 결제 SaaS 에 부적합.
Compliance¶
db/queries/{domain}/*.sql에 쿼리 정의sqlc.yaml에서 도메인별 패키지 분리 설정- 생성 코드는
engine/{domain}/adapter/persistence/sqlc/에 위치 - 다른 도메인의 sqlc 패키지를 import 금지 (import 검사)
- 동적 쿼리는 sqlc 외
squirrel등 query builder 사용 허용
Revisit triggers¶
- sqlc 의 PostgreSQL 신기능 지원이 6개월 이상 지연되면 재평가
- 쿼리 수가 폭증하여
.sql파일 관리가 부담되면 대안 검토