완료일: 2026-09-09
SQLite와 PostgreSQL이 공통 Alembic 실행기를 사용한다. PostgreSQL은 Pyodide의 Alembic → SQLAlchemy → pglite_dbapi → 동기 Worker RPC → PGlite 경로로 실제 online migration을 실행한다.
공통 API는 createWorkspace, runAlembic, readFile, writeFile, inspect, close를 제공한다. 한 client는 하나의 workspace와 DB 모드를 소유한다. PostgreSQL은 격리 헤더가 없으면 Worker 생성 전에 POSTGRESQL_UNAVAILABLE로 거절된다.
init, 수동 revision, autogenerate, upgrade/downgrade, current/history/heads/branches/show/merge를 두 모드에서 실행한다.- 파일 변경, ScriptDirectory 기반 revision DAG, Inspector 기반 schema, 실제
alembic_version과 전후 diff를 같은 응답 계약으로 반환한다. - PostgreSQL env는 SQLite batch migration을 사용하지 않는다. dialect의 단일 연결 pool을 사용하며 성공·실패 모두 연결을 정리한다.
- 원래 dialect로 compile한 컬럼 타입을 보존한다. NUMERIC, BOOLEAN, timezone timestamp, UUID, JSONB, 배열 타입을 검증했다.
- Inspector의 identity 조회에 필요한 문자열 bind cast와 JSON 원문 전달을 보완했다.
- 실패한 명령의 traceback, SQLSTATE, detail, hint를 보존하고, 별도 DB 조회로 실패 후 상태를 반환한다.
- 중복 요청은
RUNTIME_BUSY로 거절한다. 전체 명령 timeout과 Worker crash 이후 빈 workspace로 자동 재시작하지 않는다.
| 흐름 | 검증한 결과 |
|---|---|
| init | 실제 Alembic 파일 생성과 DB별 연결 URL |
| 수동 revision | 생성한 파일 편집과 실제 테이블 생성 |
| upgrade/downgrade | 테이블·컬럼 변화, DB current revision 이동 |
| autogenerate | 모델 변경의 revision 생성·검토·적용·되돌리기 |
| branch/merge | Alice/Bob 독립 컬럼 변경, multiple-head 오류, 두 version 행, merge 후 단일 head |
이 흐름은 두 모드에 동일한 명령을 실행하는 공통 E2E로 검증한다. actor workspace 복제와 학습용 설명·validator는 T7 작업이다.
PostgreSQL 전용 검증은 PK/FK/unique/check/index와 identity 컬럼 조회, 변경 없는 모델의 빈 autogenerate, VARCHAR 길이·nullable의 ALTER TABLE과 downgrade를 포함한다.
CREATE TABLE이후 잘못된 SQL로 upgrade가 실패하면 PostgreSQL에서는 새 테이블과 revision 변경이 rollback된다.- 동일한 SQLite migration에서는 현재 sqlite3 transaction 동작에 따라 생성된 테이블이 남는다. 두 엔진의 차이를 실제 snapshot으로 확인한다.
- PostgreSQL downgrade에서 INSERT·ADD COLUMN 후 unique violation을 발생시켜 schema와 version이 복구되는지 확인한다. 수정한 downgrade에서 실제 행 개수가 원래대로인지 검증한 뒤 정상 완료한다.
- 실패 직후
inspect()결과가 명령 응답의after상태와 일치한다.
- 공통 client:
src/runtime/alembic-runtime-client.ts,src/runtime/sqlite-runtime-client.ts - 공통 Python 실행기:
src/runtime/python/alembic_runtime.py(sqlite_runtime.py에서 이동) - Worker·dialect:
src/runtime/pyodide.worker.ts,src/runtime/pglite.worker.ts,src/runtime/python/pglite_sqlalchemy.py - 계약·테스트 hook:
src/runtime/protocol.ts,src/runtime/test-hook.ts,src/vite-env.d.ts,package.json - 단위 테스트:
src/runtime/alembic-runtime-client.test.ts,src/runtime/protocol.test.ts - 브라우저 테스트:
tests/e2e/alembic-parity.spec.ts(sqlite-alembic.spec.ts에서 이동),tests/e2e/postgresql-alembic.spec.ts - 문서:
README.md,docs/SPEC.md,docs/TASKS.md,docs/T5.md
모든 명령은 프로젝트 루트에서 mise exec -- 환경으로 실행했다.
pnpm lint: 통과pnpm test: 6개 파일, 22개 테스트 통과pnpm test:e2e --workers=1: Chromium·Firefox·WebKit 전체 39개 테스트 통과pnpm build: TypeScript 검사, production build, 개별 정적 파일 25 MiB 미만 검사 통과
새 dependency는 추가하지 않았다. 기존 PGlite 패키지 내부의 direct eval 관련 Vite 경고는 남아 있다.
- T6: 편집기·터미널·graph·schema 화면에 공통 client 연결
- T7: 학습 가이드·validator, Alice/Bob workspace 복제·통합
- T8: 메모리 DB와 파일의 checkpoint, 새로고침·timeout·Worker crash 후 통합 복구
현재 DB와 파일은 세션 내 실습 상태이며 영속 저장을 보장하지 않는다. 일반 migration 실패 후 rollback/재실행은 검증했지만, 실행기 자체가 종료된 뒤의 복구는 아직 제공하지 않는다.
Commit 메시지: feat: PostgreSQL Alembic 실습과 SQLite·PostgreSQL 기능 동등성 검증 구현