그 두려운 Alembic NotNullViolation 오류 (그리고 이를 극복하는 방법)
Source: Dev.to
무슨 일이 있었나요?
organizations 라는 테이블에 귀중한 데이터가 가득 들어 있다고 상상해 보세요. 여기서 plan 이라는 새 컬럼을 추가하려고 합니다.
컬럼을 NOT NULL 로 추가하면 모든 행에 값이 있어야 합니다. 하지만 테이블에 이미 행이 존재하므로 PostgreSQL은 변경을 거부합니다:
기존 데이터에 기본값 없이 NOT NULL 컬럼을 추가하는 것은 미리 설문지를 주지 않은 사람에게 설문을 작성하게 하는 것과 같습니다. 답을 몰라서 당황하게 되죠.
빠른 해결책: 기본값 추가
op.add_column(
'organizations',
sa.Column('plan', sa.String(), nullable=False, server_default='free')
)
- 기존 행들은 자동으로
'free'값을 갖게 됩니다. - 마이그레이션 후 필요하다면 기본값을 제거할 수 있습니다.
더 제어된 접근법: NULL 허용 후 채우기
# 1. 컬럼을 nullable 로 추가
op.add_column(
'organizations',
sa.Column('plan', sa.String(), nullable=True)
)
UPDATE organizations SET plan = 'free' WHERE plan IS NULL;
# 3. 컬럼을 NOT NULL 로 변경
op.alter_column('organizations', 'plan', nullable=False)
- NOT NULL 제약을 적용하기 전에 행마다 맞춤 로직을 적용할 수 있는 기회를 제공합니다.
마이그레이션 전에 수동으로 준비하기
- 테이블을 수동으로 업데이트합니다(예:
UPDATE문 사용). - 컬럼을 NOT NULL 로 추가하는 Alembic 마이그레이션을 실행합니다.
이제 기존 행들이 준비되었으므로 PostgreSQL이 오류를 발생시키지 않습니다.
기존 행이 있는 테이블에 NOT NULL 컬럼을 추가하는 것은 붐비는 파티에 새로운 규칙을 추가하는 것과 같습니다: 계획을 제공하지 않으면 누군가 불만을 가질 수 있죠. 항상 기존 데이터를 고려하세요—PostgreSQL에 기본값을 주거나, 기존 행을 업데이트하거나, 두 가지를 모두 수행하십시오.
Alembic 오류는 겁을 주는 것처럼 보이지만, 실제로는 데이터베이스가 말하는 것입니다:
“내 데이터가 깨지는 걸 너무 사랑해서 막을 수 없어요. 제대로 해봅시다.”