9강. 테이블에 컬럼 추가

0. 학습 목표
→ 실제 스키마를 바꾼 뒤, 5강에서 만든 절차를 그대로 다시 실행해 문서와 코드가 어떻게 되는지 확인합니다.
0.1 학습 목적과 선수 조건
5강에서 "스키마가 변경되면 테이블 명세서와 schema.md를 다시 생성한다"는 규칙을 CLAUDE.md에 등록했습니다.
지금까지는 이 규칙을 설명만 했고 실제로 실행해 본 적은 없습니다.
이 강의는 그 규칙을 처음으로 실제 실행해 보는 강의입니다.
새 프레임워크나 새 문법을 배우지 않습니다. 다음 한 가지만 확실히 확인하는 것이 목표입니다.
- 스키마가 바뀐 뒤에도 개발자용 산출문과 Claude Code용 문맥을 실제 구조를 다시 일치시킬 수 있는가?
이 강의는 다음 상태에서 시작합니다.
- 5강에서
schema_snapshot.json,schema_descriptions.yaml,table_spec.xlsx,schema.md를 생성했고,CLAUDE.md에 일곱 개 규칙을 등록했습니다. - 7강에서
inventory_service.py로 재고 부족 상품 조회 기능을 완성했습니다. - 8강에서 PySide6 화면에 조회 결과를 연결했습니다.
inventoryDB에products8건,stock_logs16건,operation_requests0건이 있고,schema_snapshot.json의 컬럼 수는products8,operation_requests10,stock_logs9입니다.
0.2 진행 순서
8강 실습 상태 확인
↓
무엇을 확인할지 정하기
↓
안전한 스키마 변경 실행하기
↓
CLAUDE.md 규칙대로 문서 재생성 절차 실행하기
↓
갱신된 문서 확인하기
↓
기존 코드가 영향받지 않는지 확인하기
↓
MCP로 최종 상태 비교하기
0.3 완성할 결과물
docs/database/
├── schema_snapshot.json # 갱신: products 컬럼 9개로 반영
├── schema_descriptions.yaml # 갱신: 새 컬럼만 검토 필요로 추가
├── table_spec.xlsx # 갱신: products 행 추가
└── schema.md # 갱신: products 컬럼 목록 갱신
이번 강의는 새 소스 파일을 만들지 않습니다. db/schema.sql에 이번 변경 내용을 반영하고, 5강에서 만든 문서 네 개를 같은 절차로 다시 생성합니다. tools/generate_table_spec.py와 7강의 app/ 파일들은 코드를 한 줄도 고치지 않습니다.
0.4 구현할 기능과 프로그램에서의 역할
이번 강의에서 확인하는 내용은 다음 한 문장으로 정리됩니다.
실제 스키마가 바뀌면, 5강과 같은 절차를 다시 실행해 사람용 문서와 AI용 문맥을 실제 구조와 일치시킨다.
그동안 실제 스키마를 몰라도 되던 코드는 계속 그대로 동작한다.
| 구분 | 이번 실습의 위치 |
| 지금 확인하는 것 | 5강에서 등록한 CLAUDE.md 규칙 6번("스키마가 변경되면 테이블 명세서와 schema.md를 다시 생성한다")을 실제 스키마 변경으로 처음 실행한다. |
| 스키마 변경 실행 주체 | 1~2강에서 스키마를 만들 때 사용한 관리자 계정이 MySQL 프롬프트에서 직접 실행한다. CLAUDE.md 규칙 4번에 따라 MCP는 DDL을 실행하지 않는다. |
| Claude Code의 역할 | 읽기 전용 mysql-inventory MCP로 바뀐 스키마를 조회하고, 그 결과로 schema_snapshot.json과 schema.md를 다시 생성한다. 스키마를 바꾸는 SQL은 실행하지 않는다. |
| 시리즈에서의 위치 | 5~9강 시리즈의 마지막 강의다. 이 강의를 마치면 "요구사항 작성 → Claude Code 구현 → 검토·승인 → 실행·데이터 검증"이라는 5강부터의 작업 방식이 스키마가 바뀌는 상황에서도 그대로 유지된다는 것을 확인하게 된다. |
✔ 핵심: 문서를 손으로 고치지 않습니다. 스키마가 바뀌면 5강과 같은 절차(스냅샷 재생성 → 설명 검토 → 도구 재실행)를 다시 실행해서 문서를 새로 만듭니다.
0.5 학습 목표
9강을 마치면 다음 작업을 할 수 있습니다.
- 스키마 변경 후 다시 만들어야 하는 자료와 그대로 두어도 되는 자료를 구분할 수 있습니다.
- 안전한 범위의 스키마 변경(추가만 하고 기존 컬럼은 건드리지 않는 변경)을 판단할 수 있습니다.
CLAUDE.md규칙에 따라 문서 재생성 절차를 순서대로 실행할 수 있습니다.- 갱신된 문서가 실제 스키마와 일치하는지 확인할 수 있습니다.
- 기존 코드가 스키마 변경에도 영향받지 않는 이유를 설명할 수 있습니다.
- MCP 조회 결과로 문서와 코드가 실제 데이터베이스와 일치하는지 최종 확인할 수 있습니다.
1. 8강 실습 상태 확인
→ 화면과 문서, 기준 데이터가 그대로 남아 있는지 확인하고 시작합니다.
1.1 VS Code와 세션 확인하기
VS Code에서 프로젝트 폴더를 열고, 통합 터미널에서 가상환경을 활성화한 뒤 비밀번호 환경변수를 설정합니다.
source .venv/bin/activate
read -s -p "INVENTORY_DB_PASSWORD: " INVENTORY_DB_PASSWORD
export INVENTORY_DB_PASSWORD
VS Code 사이드바에서 Claude Code 세션을 열고 MCP 연결 상태를 확인합니다.
/mcp
8강 화면도 한 번 실행해 정상 동작을 확인합니다.
python -m app.main
표에 웹캠(부족 3), USB-C 허브(부족 2) 순서로 2건이 표시되면 정상입니다. 확인 후 창을 닫습니다.
1.2 기준 데이터와 문서 확인하기
Claude Code 세션에 다음과 같이 요청합니다.
mysql-inventory MCP로 다음을 확인해줘.
- products, stock_logs, operation_requests의 행 수
- docs/database/schema_snapshot.json에 기록된 각 테이블의 컬럼 수
내가 결과를 직접 확인할 것이므로, 결론을 먼저 단정하지 마.
5강, 7강, 8강에서 확인한 값과 같아야 합니다.
▶ 지금 해보세요
- 가상환경 활성화, 비밀번호 환경변수 설정,
/mcp확인을 순서대로 진행합니다. - 8강 화면을 실행해 조회 결과를 확인합니다.
- 위 요청으로 행 수와 문서상의 컬럼 수를 확인합니다.
✔ 확인 기준: 행 수가 8 / 16 / 0이고, schema_snapshot.json의 컬럼 수가 products 8, operation_requests 10, stock_logs 9입니다. 이 값이 이번 강의를 시작하는 기준값입니다.
2. 무엇을 확인할지 정하기
→ 스키마 변경 후 다시 만들 자료와 그대로 두어도 되는 자료를 먼저 구분합니다.
2.1 다시 만들 것과 그대로 둘 것 구분하기
| 구분 | 스키마 변경 후 상태 |
schema_snapshot.json, schema_descriptions.yaml, table_spec.xlsx, schema.md |
다시 만든다 (5강 절차를 그대로 재실행) |
tools/generate_table_spec.py |
그대로 둔다 (입력 파일만 바뀌고 도구 코드는 그대로) |
app/repositories/inventory_repository.py, inventory_service.py |
그대로 둔다 (필요한 컬럼만 명시적으로 조회하므로 새 컬럼과 무관) |
이번 강의의 핵심은 "무엇을 다시 만들어야 하는가"를 구분하는 것입니다. 스키마가 바뀌었다고 해서 프로젝트의 모든 파일을 다시 만들 필요는 없습니다.
2.2 안전한 스키마 변경 정하기
아무 변경이나 실습에 쓰지 않습니다. 다음 조건을 만족하는 변경만 안전하다고 판단합니다.
- 기존 컬럼을 지우거나 이름을 바꾸지 않는다 (기존 코드가 계속 동작해야 한다)
- 새 컬럼은
NULL을 허용한다 (기존 행 8개에 기본값을 강제로 넣지 않아도 된다) - 기존 제약 조건(PK, FK, UK, CK)을 건드리지 않는다
이 조건을 만족하는 변경으로, products 테이블에 상품 메모를 적는 memo 컬럼(VARCHAR(255), NULL 허용)을 추가합니다.
▶ 지금 해보세요
- 다시 만들 자료와 그대로 둘 자료를 표로 정리합니다.
- 이번에 추가할
memo컬럼이 세 가지 안전 조건을 만족하는지 확인합니다.
✔ 확인 기준: 다시 만들 문서 네 개와 그대로 둘 파일들을 구분했고, memo 컬럼이 NULL 허용이며 기존 컬럼·제약 조건을 건드리지 않는다는 것을 설명할 수 있습니다.
3. 안전한 스키마 변경 실행하기
→ 관리자 계정이 MySQL 프롬프트에서 직접 ALTER TABLE을 실행합니다.
3.1 ALTER TABLE 실행하기
CLAUDE.md 규칙 4번("MySQL MCP를 사용하여 INSERT, UPDATE, DELETE, DDL을 실행하지 않는다")에 따라,
스키마를 바꾸는 ALTER TABLE은 Claude Code나 MCP가 아니라
사람이 관리자 계정으로 쉘 프롬프트에서 직접 실행합니다.

mysql -u root -p inventory
MySQL 프롬프트가 뜨면 다음 SQL을 실행합니다.

ALTER TABLE products
ADD COLUMN memo VARCHAR(255) NULL COMMENT '상품 메모';
이어서 db/schema.sql 파일에도 같은 컬럼 정의를 추가해, 다음에 이 프로젝트를 처음부터 만들 때도 같은 구조가 만들어지도록 합니다.
3.2 MCP로 변경 확인하기
Claude Code 세션에 다음과 같이 요청합니다.
mysql-inventory MCP로 products 테이블의 컬럼 목록을 확인해줘.
조건:
- SELECT와 SHOW만 사용하고, 결과를 표로 보여줘.
내가 결과를 직접 확인할 것이므로, 결론을 먼저 단정하지 마.
결과에 memo 컬럼이 포함되어 있고, products 컬럼 수가 8에서 9로 늘어난 것이 확인되어야 합니다.

▶ 지금 해보세요
- 관리자 계정으로 MySQL 프롬프트에 접속해
ALTER TABLE을 실행합니다. db/schema.sql에 같은 컬럼 정의를 추가합니다.- MCP로 변경된 컬럼 목록을 확인합니다.
✔ 확인 기준: products에 memo 컬럼이 추가되어 있고, MCP 조회 결과의 컬럼 수가 9입니다.
4. CLAUDE.md 규칙대로 문서 재생성 절차 실행하기
→ 5강에서 정리한 절차(스냅샷 재생성 → 설명 검토 → 도구 재실행)를 순서대로 따라갑니다.
4.1 schema_snapshot.json 다시 생성 요청하기
5강의 절차를 다시 떠올립니다.
실제 스키마 변경 발생
↓
읽기 전용 MCP로 변경된 스키마 조회
↓
schema_snapshot.json 다시 생성
↓
schema_descriptions.yaml에 추가된 항목만 검토
↓
python tools/generate_table_spec.py 실행
↓
table_spec.xlsx와 schema.md 갱신 확인
Claude Code 세션에 다음과 같이 요청합니다.

읽기 전용 MySQL MCP로 inventory DB의 실제 스키마를 다시 조회해서
docs/database/schema_snapshot.json을 갱신해줘.
조건:
- 5강에서 만든 것과 같은 형식을 유지한다.
- products 테이블의 컬럼 목록에 이번에 추가된 memo 컬럼이
포함되어야 한다.
- 실행할 SELECT SQL을 먼저 보여준다.
내가 SQL과 계획을 승인하기 전에는 실행하지 마.
4.2 schema_descriptions.yaml에서 추가된 항목만 검토하기
schema_descriptions.yaml을 다시 생성하면, 5강에서 이미 검토·확정한 기존 컬럼의 논리명·설명은 그대로 유지되고 새로 추가된 memo 컬럼만 검토 필요로 표시되어야 합니다. Claude Code 세션에 다음과 같이 요청합니다.
docs/database/schema_descriptions.yaml을 다시 생성해줘.
조건:
- 기존에 확정된 논리명과 설명은 그대로 유지한다.
- 새로 추가된 products.memo 컬럼만 검토 필요로 표시한다.
- 기존 항목의 논리명이나 설명을 임의로 바꾸지 않는다.
diff로 보여주고 승인을 기다려줘.
memo의 논리명을 "상품 메모"로, 설명을 "판매자가 상품에 대해 자유롭게 남기는 참고용 텍스트"로 직접 채웁니다. 5강에서 배운 대로, 근거가 있는 값만 직접 채우고 검토 필요 표시를 지웁니다.
4.3 generate_table_spec.py 다시 실행하기
문서를 만드는 도구 자체는 수정하지 않습니다. 입력 파일(스냅샷, 설명 파일)만 바뀌었으므로 같은 도구를 그대로 다시 실행합니다.
python tools/generate_table_spec.py
5강과 같은 형식의 검증 출력이 나타나야 합니다.

[생성] docs/database/table_spec.xlsx
[생성] docs/database/schema.md
[검증] 테이블 수: 스냅샷 3 / 명세서 3 / schema.md 3 → 일치
▶ 지금 해보세요
- 4.1 요청으로
schema_snapshot.json을 갱신합니다. - 4.2 요청으로
schema_descriptions.yaml을 갱신하고,memo항목을 직접 채웁니다. python tools/generate_table_spec.py를 실행합니다.
✔ 확인 기준: 검증 출력에서 테이블 수가 3으로 일치하고, schema_descriptions.yaml에는 memo 외에 새로운 검토 필요 항목이 없습니다.
5. 갱신된 문서 확인하기
→ 새로 생성된 두 문서에 변경 사항이 정확히 반영되었는지 눈으로 확인합니다.
5.1 table_spec.xlsx 확인하기
docs/database/table_spec.xlsx를 열어 products 시트를 확인합니다. 기존 8개 컬럼 행 아래에 memo 행이 새로 추가되어 있어야 하고, 논리명·설명에 "검토 필요"가 남아 있지 않아야 합니다.

5.2 schema.md 확인하기
docs/database/schema.md를 열어 products 부분을 확인합니다. 컬럼 목록에 memo가 포함되어 있어야 합니다.

마지막으로 Excel 명세서와 schema.md의 products 컬럼 수가 서로 같은지 확인합니다. 두 문서는 같은 스냅샷에서 생성되므로 다르면 생성 도구의 오류입니다.
▶ 지금 해보세요
table_spec.xlsx의products시트에서memo행을 확인합니다.schema.md의products컬럼 목록에서memo를 확인합니다.
✔ 확인 기준: table_spec.xlsx와 schema.md 모두 products 컬럼 수가 9이고, 두 문서의 memo 논리명·설명이 서로 같습니다.
6. 기존 코드가 영향받지 않는지 확인하기
→ 7강 코드를 다시 실행해, 컬럼이 추가되어도 문제가 없는 이유를 직접 확인합니다.
6.1 7강 코드 재실행하기
7강, 8강 코드를 한 줄도 고치지 않은 채로 다시 실행합니다.

pytest -v
python -m app.services.inventory_service
python -m app.main
세 명령 모두 8강까지와 똑같은 결과(테스트 2개 PASSED, 웹캠·USB-C 허브 2건)가 나와야 합니다.
6.2 왜 영향받지 않는지 설명하기
inventory_repository.py의 SQL을 다시 봅니다.

SELECT product_id, product_name, stock_quantity, reorder_level
FROM products
WHERE stock_quantity <= reorder_level
ORDER BY product_id ASC
이 SQL은 SELECT *가 아니라 필요한 컬럼 네 개만 이름으로 나열합니다. 그래서 products에 memo 컬럼이 새로 생겨도 이 SQL의 결과는 전혀 바뀌지 않습니다.
만약 7강에서 SELECT *를 썼다면, 반환되는 값에 memo가 예고 없이 추가되어 이후 코드가 그 값을 어떻게 처리할지 다시 검토해야 했을 것입니다.
✔ 핵심: 컬럼을 이름으로 명시하는 SQL은 스키마에 컬럼이 추가되어도 안전합니다. SELECT *는 스키마가 바뀌면 반환값이 예고 없이 바뀔 수 있어 위험합니다.
▶ 지금 해보세요
pytest -v,python -m app.services.inventory_service,python -m app.main을 순서대로 실행합니다.inventory_repository.py의 SQL에서 컬럼이 이름으로 나열되어 있는지 확인합니다.
✔ 확인 기준: 세 명령의 결과가 8강까지와 동일하고, SQL에 SELECT *가 없습니다.
7. MCP로 최종 상태 비교하기
→ 문서, 코드, 실제 데이터베이스 세 가지가 서로 일치하는지 마지막으로 대조합니다.
7.1 MCP로 최종 스키마 확인하기
Claude Code 세션에 다음과 같이 요청합니다.

mysql-inventory MCP로 다음을 확인해줘.
- products 테이블의 컬럼 전체 목록과 개수
- products, stock_logs, operation_requests의 행 수
조건:
- SELECT와 SHOW만 사용하고, 결과를 표로 보여줘.
내가 결과를 직접 확인할 것이므로, 결론을 먼저 단정하지 마.
7.2 세 가지를 표로 비교하기
| 비교 항목 | 문서(schema.md·table_spec.xlsx) | MCP 조회 결과 |
products 컬럼 수 |
9 | 9 |
memo 컬럼 포함 여부 |
포함 | 포함 |
| 행 수(products / stock_logs / operation_requests) | — | 8 / 16 / 0 (변경 없음) |
행 수는 스키마 변경(컬럼 추가)과 무관하므로 5강 이후와 같아야 합니다. 컬럼을 추가하는 것과 데이터를 바꾸는 것은 서로 다른 작업입니다.
▶ 지금 해보세요
- MCP로 최종 스키마와 행 수를 조회합니다.
- 문서 내용과 MCP 결과를 표로 비교합니다.
✔ 확인 기준: 문서의 products 컬럼 수·memo 포함 여부가 MCP 조회 결과와 일치하고, 행 수는 8 / 16 / 0으로 변경 없이 유지됩니다.
8. 오류 해결하기
→ 설정을 무작정 다시 만들지 않습니다. 다음 순서로 원인을 좁힙니다.
8.1 증상별 확인 순서
관리자 계정 권한 확인 → ALTER TABLE 실행 여부 확인 → 스냅샷 재생성 확인 → 도구 재실행 확인
| 증상 | 먼저 확인할 항목 | 해결 방향 |
ALTER TABLE 실행 시 권한 오류 |
관리자 계정으로 접속했는가 | inventory_reader·inventory_operator·inventory_app이 아닌 관리자 계정으로 재접속 |
MCP로 조회해도 memo 컬럼이 안 보임 |
ALTER TABLE이 inventory DB에 실제로 실행되었는가 |
USE inventory; 후 다시 실행했는지 확인 |
schema_snapshot.json을 다시 생성해도 컬럼 수가 그대로 8 |
스냅샷 재생성 요청이 실제로 다시 실행되었는가 | 4.1 요청을 다시 보내고, 생성된 파일의 타임스탬프 확인 |
generate_table_spec.py 실행 결과 테이블 수 불일치 |
스냅샷과 설명 파일을 같은 시점에 갱신했는가 | 4.1, 4.2를 순서대로 다시 실행한 뒤 도구 재실행 |
| 7강 코드 실행 시 오류 발생 | SQL에 SELECT *가 있었는가 |
컬럼을 이름으로 나열하도록 inventory_repository.py 확인(수정하지 않아도 되는 것이 정상) |
💡 팁: 7강 코드에서 오류가 난다면 코드를 고치기 전에, 애초에 컬럼을 이름으로 나열했는지부터 확인합니다. 이 강의의 목적은 코드를 고치는 것이 아니라 "안 고쳐도 되는 이유"를 확인하는 것입니다.
9. 이번 강의 완료 기준
→ 확인한 내용을 체크리스트로 정리하고, 5강부터 이어온 시리즈를 마무리합니다.
9.1 최종 체크리스트
☐ 스키마 변경 후 다시 만들 자료와 그대로 둘 자료를 표로 구분했다
☐ 관리자 계정으로 products에 memo 컬럼(NULL 허용)을 추가했고, db/schema.sql에도 반영했다
☐ schema_snapshot.json, schema_descriptions.yaml을 5강과 같은 절차로 다시 생성했다
☐ table_spec.xlsx와 schema.md의 products 컬럼 수가 9로 일치한다
☐ 7강·8강 코드를 한 줄도 고치지 않고 다시 실행해 같은 결과를 확인했다
☐ 컬럼을 이름으로 나열하는 SQL이 스키마 변경에 안전한 이유를 설명할 수 있다
☐ MCP 조회 결과로 문서·코드·실제 데이터베이스가 서로 일치함을 확인했다
9.2 완성 구조
inventory-mysql-app/
├── CLAUDE.md
├── db/
│ └── schema.sql (memo 컬럼 정의 추가)
├── docs/database/
│ ├── schema_snapshot.json (갱신)
│ ├── schema_descriptions.yaml (갱신)
│ ├── table_spec.xlsx (갱신)
│ └── schema.md (갱신)
├── tools/
│ └── generate_table_spec.py (변경 없음)
├── app/
│ ├── db.py
│ ├── repositories/inventory_repository.py
│ ├── services/inventory_service.py
│ ├── ui/inventory_window.py
│ └── main.py
└── tests/
└── test_inventory_service.py
9.3 이번 강의에서 아직 하지 않는 작업
이번 강의는 컬럼 추가라는 안전한 범위의 변경만 다룹니다. 다음 작업은 다루지 않습니다.
- 기존 컬럼의 이름을 바꾸거나 삭제하는 변경 (기존 코드에 직접 영향을 준다)
memo컬럼을 화면(8강 UI)이나 조회 기능(7강)에 실제로 노출하는 작업- 여러 사람이 동시에 스키마를 변경하는 상황의 충돌 처리
9.4 참고 문서
[OG 카드 자리: MySQL 공식 문서 — ALTER TABLE 문법]
기존 컬럼을 삭제하거나 타입을 바꾸는 변경이 왜 더 위험한지는 MySQL 공식 문서의 "ALTER TABLE Statement" 페이지에서 확인할 수 있습니다.
→ 시리즈를 마치며: 5강부터 9강까지, "자연어 요구사항 작성 → Claude Code 구현 → VS Code diff로 검토·승인 → 실행과 MCP 조회로 검증"이라는 작업 방식을 조회 기능, 화면 통합, 스키마 변경 대응까지 반복했습니다. 이 시리즈의 산출물(inventory-mysql-app 프로젝트)은 계속 유지·확장할 수 있는 상태로 남아 있습니다.
10. 실습 과제
→ 다른 테이블에 컬럼을 추가해 보면서 재생성 절차를 스스로 반복합니다.
10.1 다른 테이블에 컬럼 추가해 보기
stock_logs 테이블에 NULL을 허용하는 note_by(VARCHAR(100)) 컬럼을 관리자 계정으로 추가합니다. 이번 강의와 같은 절차(스냅샷 재생성 → 설명 검토 → 도구 재실행 → 문서 확인)를 처음부터 끝까지 스스로 실행합니다.
10.2 안전하지 않은 변경 판단해 보기
다음 세 가지 변경이 2.2의 안전 조건 중 어느 것을 위반하는지 각각 적어 봅니다. 실제로 실행하지는 않습니다.
products.product_name컬럼의 이름을name으로 바꾸는 변경products.reorder_level컬럼을 삭제하는 변경- 새 컬럼을 추가하면서 기존 8개 행에 대한 기본값 없이
NOT NULL로 지정하는 변경
10.3 제출물
다음 세 가지를 캡처하거나 정리하여 제출합니다.
- 10.1에서 갱신된
schema.md의stock_logs부분 캡처 - 10.1 실행 후 7강·8강 코드가 여전히 정상 동작하는 화면 캡처
- 10.2의 세 가지 변경이 위반하는 안전 조건 목록