Django 포스팅
Doyeon0430 | 2023년 08월 18일
이번시간에는 Django에서 PostgreSQL 데이터베이스를 사용할 때 발생하는 오류에 대해 살펴보겠습니다.
"django.db.utils.ProgrammingError: 오류: [모델명.필드명] 칼럼 없음",
"psycopg2.errors.UndefinedTable: 오류 [모델명.필드명] 칼럼 없음",
"django.db.utils.ProgrammingError: 오류 [필드명] 칼럼은 [테이블] 릴레이션(relation)에 없음",
"django.db.utils.ProgrammingError: 오류: [필드명] 이름의 칼럼은 [모델명] 릴레이션에 이미 있습니다"
다음과 같은 오류 메세지가 발생할 때 해결하는 방법에 대해 알아보겠습니다.
해당 오류는 Django와 PostgreSQL 데이터베이스가 서로 충돌해서 생기는 현상입니다.
저는 engineer라는 앱에서 Network라는 모델에 code라는 필드를 추가할 때 오류가 발생했습니다.
아래 내용은 직접 발생한 오류 메세지입니다.
1. 마이그레이션 오류 발생
>> python manage.py migrate
Traceback (most recent call last):
File "C:\Users\김도연\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\backends\utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedColumn: 오류: engineer_network.code 칼럼 없음
LINE 1: ...twork"."create_date", "engineer_network"."photo", "engineer_...
[...내용 생략...]
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: 오류: engineer_network.code 칼럼 없음
LINE 1: ...twork"."create_date", "engineer_network"."photo", "engineer_..
python manage.py makemigrations이랑 python manage.py migrate를 사용해도 계속 똑같은 문구만 나옵니다.
2. models.py
class Network(models.Model):
subject = models.CharField(max_length=200)
meta = models.CharField(max_length=130)
htmlcontent = HTMLField()
create_date = models.DateTimeField(auto_now_add=True)
photo = models.ImageField(upload_to='network/')
code = models.CharField(max_length=20, choices=[('공군', '공군'), ('네트워크', '네트워크'), ('자격증','자격증')]) # 새로 추가한 코드
def __str__(self):
return self.subject
def get_absolute_url(self):
return f'/engineer/network/{self.pk}/'
class Meta:
verbose_name_plural = '5. 네트워크 포스팅'
이런식으로 Network 모델에 code라는 필드를 추가했는데 뜬금없이 오류가 발생했습니다.
3. pgAdmin 4
-- Table: public.engineer_network
-- DROP TABLE IF EXISTS public.engineer_network;
CREATE TABLE IF NOT EXISTS public.engineer_network
(
id integer NOT NULL DEFAULT nextval('engineer_network_id_seq'::regclass),
subject character varying(200) COLLATE pg_catalog."default",
meta character varying(130) COLLATE pg_catalog."default",
htmlcontent text COLLATE pg_catalog."default",
create_date timestamp without time zone DEFAULT now(),
photo character varying(255) COLLATE pg_catalog."default"
CONSTRAINT engineer_network_pkey PRIMARY KEY (id)
)
직접 engineer_network 테이블로 들어가 SQL을 확인해보니 추가한 필드가 없었습니다.
맨 처음으로 마이그레이션을 폴더에 파일들을 정리했습니다.
오류가 발생한 앱 내부에 migrations 폴더로 가서 __init__.py을 제외한 모든 파일 제거합니다.
1. 경로 위치
├── engineer/
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
└── migrations/
├── __init__.py
├── 0001_initial.py # 제거
├── 0002_django_app.py # 제거
├── 0002_django_app.py # 제거
└── ...
[00XX_이름] 으로 된 파일을 모두 제거합니다.
장고에서 마이그레이션 파일들이 계속 쌓이면 충돌이 발생할 수 있습니다.
그렇기 때문에 수시로 지워주는 걸 권장합니다.
2. cmd 명령어
python manage.py makemigrations
python manage.py migrate
다음으로 위와 같은 명령어를 입력하면 됩니다.
혹시나 마이그레이션 파일이 생성 안되고 똑같은 오류가 발생할 수 있습니다.
psql에서 직접 칼럼을 추가하면 되기때문에 큰 문제는 없습니다.
다음으로 pgAdmin 4와 psql 쉘을 이용해서 칼럼을 추가하겠습니다.
pgAdmin 4에 로그인을 하고 오류가 난 테이블로 들어갑니다.
1. pgAdmin 4
위 사진처럼 추가하고 싶은 필드가 입력되어 있으면 정상적으로 작동됩니다.
하지만 필드가 없을 경우 직접 추가를 해야합니다.
[경로 : Servers → PostgreSQL 15 → Database → 데이터베이스_이름 → Schemas → Tables → 모델명]
2. psql 명령어
postgres=> ALTER TABLE public.engineer_network
postgres=> ADD code character varying(20) COLLATE pg_catalog."default";
ALTER TABLE
engineer_network 테이블에 새로운 컬럼을 추가하는 명령어입니다.
ALTER TABLE 명령어로 ADD를 사용했습니다.
3. cmd 명령어
python manage.py makemigrations
python manage.py migrate
다시한번 진행하면 정상적으로 마이그레이션 파일이 생성됩니다.
하지만 migrate를 실행할 때 또 오류가 발생할 수 있습니다.
4. migrate 오류 발생
>> python manage.py migrate
System check identified some issues:
[... 내용 생략 ....]
return self.cursor.execute(sql)
psycopg2.errors.DuplicateColumn: 오류: "code" 이름의 칼럼은 "engineer_network" 릴레이션에 이미 있습니다
쉘을 통해 직접 테이블에 값을 넣어서 생긴 오류입니다.
장고에 마이그레이션과 스키마가 겹치기 때문에 migrate가 안됩니다.
5. cmd 명령어
>> python manage.py migrate --fake
System check identified some issues:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, django_celery_beat, django_celery_results, engineer, movie, myprofile, mywork, sessions, sites
Running migrations:
Applying engineer.0005_network_code... FAKED
--fake 옵션을 추가해서 스키마에 변경없이 마이그레이션을 실행시킬 수 있습니다.
6. 컬럼 추가 결과화면
정상적으로 입력되면서 마이그레이션 파일이 저장됐습니다.
댓글 (0)
간편 댓글 작성