Skip to content

Latest commit

 

History

History
71 lines (49 loc) · 4.85 KB

File metadata and controls

71 lines (49 loc) · 4.85 KB

T5 — PostgreSQL Alembic 기능 동등성

완료일: 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 기능 동등성 검증 구현