엔지니어링 가이드

DB 바꾸기

표(스키마)는 서버마다 그 언어의 마이그레이션 도구로 바꾼다. 셋 다 서버가 뜰 때 아직 적용하지 않은 마이그레이션을 적용하고, 테스트도 테스트 DB 에 같은 마이그레이션을 적용한다. DB 엔진은 Postgres 가 기본이고 서버마다 따로 바꿀 수 있다(ADR-0004).

스키마

서버 도구 파일 새 마이그레이션
notes (Node) node-pg-migrate servers/notes/migrations/NNNN_설명.sql (-- Up Migration · -- Down Migration) pnpm --filter @app/notes migrate create <설명>
activity (Spring) Flyway servers/activity/storage/db-core/src/main/resources/db/migration/V{n}__설명.sql 다음 번호로 파일을 더한다
tags (FastAPI) Alembic servers/tags/migrations/versions/NNNN_설명.py (op.execute 로 SQL) uv run alembic revision -m <설명> --rev-id NNNN (그 폴더에서)
  • 스키마를 바꿀 때는 다음 번호의 새 파일을 더한다. main 에 들어간 마이그레이션을 고치면 이미 적용한 DB 의 기록과 달라진다. activity(Flyway)는 hook 도 막는다.
  • 브랜치에서 만든 마이그레이션은 main 을 받을 때마다 번호가 main 의 마지막보다 뒤인지 본다. 겹치면 서버가 뜨지 않을 수 있다 → troubleshooting.md.
  • 적용 기록은 표에 남는다: pgmigrations · flyway_schema_history · alembic_version. 테스트의 DB 정리는 이 표를 남기고 나머지만 비운다.
  • notes 의 마이그레이션이 바꾸는 종류마다 예다: 0002_notes 는 데이터를 옮긴다(메모 하나를 담던 표 → 메모 목록 표 notes, 예전 표는 지운다), 0003_note_tags 는 기존 행이 있는 표에 기본값과 함께 열을 더한다.
  • pnpm gen 은 마이그레이션을 돌리지 않는다. 문서 생성에는 DB 가 필요 없다.

개발 DB 를 처음부터

스키마가 꼬이면 그 서버의 개발 · 테스트 DB 를 다시 만든다. 서버가 다시 뜰 때 마이그레이션이 처음부터 적용된다. 그 서버의 개발 데이터는 지워지고 다른 서버의 DB 는 그대로다. 아래는 notes 의 예다. 다른 서버는 notes 를 그 서버 이름(tags · activity)으로 바꾼다.

docker compose -f docker/docker-compose.middleware.yaml exec db psql -U app -d postgres \
  -c 'DROP DATABASE notes WITH (FORCE)' -c 'CREATE DATABASE notes' \
  -c 'DROP DATABASE notes_test WITH (FORCE)' -c 'CREATE DATABASE notes_test'

모든 서버를 처음부터 하려면 Postgres 볼륨을 지우고 다시 띄운다.

docker compose -f docker/docker-compose.middleware.yaml down -v && pnpm infra

다른 DB 로

테스트도 그 엔진으로 돈다(ADR-0003). Postgres 에 묶인 곳:

고칠 곳
인프라 docker/docker-compose.middleware.yaml 의 db(이미지 · healthcheck · 포트), docker/postgres/init.sql(서버마다 DB · _test), docker/docker-compose.yaml 의 PGHOST, docker/.env.example 의 POSTGRES_PORT
notes package.json 의 postgres · pg(드라이버), src/storage/db.ts(연결) · migrate.ts, migrations/*.sql, src/storage/*.ts(SQL), tests/support/api.ts 의 reset
activity storage/db-core/build.gradle.kts 의 org.postgresql:postgresql · flyway-database-postgresql, application.properties · CoreApiTest.java 의 jdbc:postgresql URL, 저장소 SQL · db/migration/*.sql, CleanDatabase
tags pyproject.toml 의 psycopg(드라이버), server/storage/db.py(연결 풀), migrations/env.py(postgresql+psycopg 연결) · versions/*.py, server/storage/*.py(SQL), tests/conftest.py 의 database · clean_db
공통 환경 변수 PG*(servers/*/.env.template 와 위 연결 코드), 문서(이 파일 · development.md · architecture.md · testing.md · 서버 AGENTS.md)
  • 테스트 정리는 마이그레이션 기록 표를 뺀 모든 표를 비운다. 지금은 pg_tables 로 표를 찾고 TRUNCATE 한다. 다른 DB 는 information_schema.tables 로 찾고, TRUNCATE 가 없거나 외래 키에 막히면 DELETE FROM.
  • BIGINT GENERATED ALWAYS AS IDENTITY 와 RETURNING 은 Postgres 문법이다. MySQL 은 AUTO_INCREMENT 와 따로 읽기, SQLite 는 INTEGER PRIMARY KEY.
  • Postgres 에 묶인 곳을 새로 만들면 위 표에도 더한다.
GitHub 에서 고치기