필자는 mysql-nodejs로만 DB-API를 다루어 보았다. django를 사용하면 DRF(Django REST Framwork)와 ORM(Object Relational Mapping)이 매우 편하다는 얘기를 들어, 회사에서 새롭게 진행하는 프로젝트의 구조를 django-postgres를 사용해보기로 했다.
이번 작업은 기존에 정리해놓은 csv를 postgres로 업로드 하는 일이었다.
우선 처음 고민했던 사항은
1. 이걸 postgres로 바로 업로드해야하는가?
2. django를 통해 업로드해야하는가?
첫 번째 방법은 django의 ORM이 어떻게 구성되는지 모르겠으나, DB와 django가 독립적으로 돌아버리니 충돌이 날 수 있다고 생각이 들었고,
두 번째 방법은 csv와 같이 큰 파일을 업로드하는데 굳이 django를 통해서 업로드하는 건 자원 낭비라는 생각이 들었다.
하지만 결론은 두 번째 방법이었다. 왜냐하면
1. csv가 거의 정제되어있다 하더라도, DB의 dataType과 맞지 않을 수도 있고,
2. csv column과 DB column이 맞지 않았다.
역시 작업을 하다보니 위 문제들 때문에 django를 통해 업로드해야겠더라.
이제 실질적인 작업 과정을 보자
먼저 django에서 app에 db에 올릴 class구조를 짜놓는다. (django document를 참고하자)
그리고 이 작업은 새로운 .py 파일을 만들어서 거기서 진행한다. 위치는 위에서 만든 django app을 import 할 수 있는 위치로 하자.
필자는 project root 폴더에서 진행했다.
django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
아마 처음 실행하면 다음과 같은 코드를 마주치게 될것이다. 왜 python파일에서 django에 접근하질 못하는건가!
에러 코드를 읽어보면 DJANGO_SETTINGS_MODULE이란 환경변수를 설정하거나, settings.configure()를 실행하라고한다.
이를 해결하기 위해서는 두 가지가 필요하다
1. DJANGO_SETTINGS_MODULE 환경변수 세팅
2. django.setup()함수 실행
django.setup()에 대해서 django document는 다음과 같이 설명하고있다.
if you’re using components of Django “standalone” – for example, writing a Python script which loads some Django templates and renders them, or uses the ORM to fetch some data – there’s one more step you’ll need in addition to configuring settings.
"or user the ORM to fetch some data"
딱 현재 우리가 원하는 상황과 동일하다.
그래서 필요한 코드는 다음과 같다
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app이름.settings")
import django
django.setup()
from 앱이름.원하는_모델이_있는_경로.models import {사용할 class들} # 중괄호는 삭제한다. (표기용)
1. os.environ.setdefault로 DJANGO_SETTINGS_MODULES를 선언해준다
2. 그리고 django.setup()을 실행한다.
자 이 상황은 project folder에 python파일을 위치 시켰을 때 이야기이고, 그 외의 폴더에서 진행하기 위해서는 다음의 코드를 추가한다.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # project folder 경로로 위치시킨다.
sys.path.append(BASE_DIR)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app이름.settings")
import django
django.setup()
from 앱이름.원하는_모델이_있는_경로.models import {사용할 class들} # 중괄호는 삭제한다. (표기용)
os.path.abspath(__file__)은 현재 파일의 경로를 나타내고
os.path.dirname을 사용할 때 마다, 부모 경로로 한 칸씩 이동한다.
그렇게해서 BASE_DIR을 project root folder로 위치시키고, BASE_DIR을 sys.path에 append하면 다른 폴더 경로에서도 django를 가져다 쓸 수 있다
sys path 에 대해서는 아래의 게시글을 추천한다.(짧다)
그리고 csv에 접근은 다음과 같이 한다.
import csv # 기본 라이브러리다
CSV_PATH = csv 경로
# encoding 설정 필요
with open(CSV_PATH, newline='', encoding='utf-8') as csvfile:
data_reader = csv.DictReader(csvfile)
for row in data_reader:
# row['컬럼명']으로 한 줄씩 접근가능
그리고 ORM을 이용해 DB에 데이터를 올리기 위해서는 for문 아래에 다음 코드를 사용한다.
parsing_data = parsing(row['정제할 컬럼명']) # parsing()에 정제 방법을 정의한다.
import한 클래스.objects.create(
클래스에서 생성한 member1 = row['컬럼명']
클래스에서 생성한 member2 = parsing_data
...
)
이 때, 추가적인 데이터 정제가 필요하면 row['컬럼명']이 아닌, 한 번 정제한 데이터를 넣어주면 된다.
이렇게 csv 업로드는 끝이다!
postgres를 쓰고 있다면 pgAdmin을 설치하여 데이터가 제대로 들어갔는지 확인해보자.
필자가 참고한 코드는 아래 포스트이다
'Programming > Django' 카테고리의 다른 글
[DRF] 귀찮은건 싫어! ViewSet 사용해보기 (0) | 2021.11.21 |
---|---|
[DRF] Serializer로 역참조의 역참조 모델 가져오기 (0) | 2021.10.22 |
[Django, Docker] gunicorn에 vscode debugger 붙이기 (0) | 2021.10.20 |
[DRF] get_queryset에서 벗어나기(get 사용) (0) | 2021.10.15 |
Django foreign key를 사용했을 때 역참조(DRF) (0) | 2021.10.15 |