본문 바로가기

문돌이 존버/Django 스터디

Django용 MySQL에 csv 파일 업로드 + 데이터를 csv 파일로 변환

반응형

csv 파일로 데이터 집어넣기

이번엔 간단하게 장고에 설정된 MySQL DB에 csv를 업로드하는 과정을 살펴보겠습니다. 장고와 MySQL을 연동하는 방법이 궁금하다면 제가 이전에 작성한 글을 참고해주시기 바랍니다. 아래 코드는 manage.py 파일이 있는 위치에 생성하면 되겠습니다.

import csv
import os
import django
import sys

# 현재 디렉토리 경로 표시
os.chdir(".")
print("Current dir=", end=""), print(os.getcwd())

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print("BASE_DIR=", end=""), print(BASE_DIR)

sys.path.append(BASE_DIR)

# 프로젝트명.settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "medchat.settings")
django.setup()

from medchat_app.models import *	

# csv 파일 경로
CSV_PATH = './db_test.csv'	

# encoding 설정 필요
with open(CSV_PATH, newline='', encoding='utf-8-sig') as csvfile:	
    data_reader = csv.DictReader(csvfile)

    for row in data_reader:
        # print(row)
        TBL_MEDICINE_INFO.objects.create(	
            symptom = row['symptom'],
            disease = row['disease'],
            medicine = row['medicine'],
            effect = row['effect'],
            usage = row['usage'],
            precautions = row['precautions'],
            reference = row['reference']
         )

위 코드에서 주의해야 할 부분은 encoding 설정인데요, 저는 처음에 인코딩 없이 작업을 진행하다가 오류 아닌 오류를 경험했습니다. 맨 첫 컬럼명에 /ufeff 라는 문자가 같이 붙어나와 symptom 컬럼이 /uffeffsymptom 이라고 표시되었습니다. 관련 오류를 해결하고자 구글링을 했고 그 해결방법을 찾아 공유합니다. 아래 내용은 frhyme.code님의 블로그 글을 참고한 것입니다. 감사합니다 ^^

/ufeff는 해당 파일이 어떤 문자열로 인코딩되었는지를 의미하는 일종의 식별자입니다. 해당 문서의 인코딩 방식을 설명하는 메타 정보라고 보시면 됩니다. 보통 이러한 방식은 해당 파일의 맨 앞에 집어넣곤 합니다.

따라서 utf-8-signature 이라는 인코딩 방식을 넘겨주면 앞의 정보를 무시하게 됩니다. 이는 해당 파일이 확실하게 utf-8로 인코딩되었음을 정확하게 전달하는 것이죠.

이와 같은 과정이 불편하다면 csv 모듈 대신 판다스의 pandas.read_csv 를 활용하시면 됩니다. 마지막으로 위 코드를 python db_test.py(db_test는 제가 설정한 파일명입니다) 명령어를 통해 실행시키면 MySQL DB에 데이터가 잘 적재된 것을 확인할 수 있습니다. 

참고로 csv 파일은 아래와 같이 편하게 컬럼과 데이터를 채워넣으시면 됩니다.

* 참고 사항: 엑셀 파일에서 boolean 값인 True, False를 입력하면 자동으로 TRUE, FALSE 처럼 대문자화 합니다. 이는 엑셀 자동 변환 기능 목록에도 없는 기능인데, 마이크로소프트 공식 입장을 읽어보면 True' ', False' ' 와 같이 띄어쓰기를 하든, 'True', 'False' 처럼 따옴표를 넣으라고 합니다. 하지만 이럴 경우, DB에 import할 때 문제가 발생하게 되죠. 결국 해결방법은 간단하게 엑셀에 0과 1을 입력하는 것입니다.


DB 데이터를 csv 파일로 변환하기

다음으로는 MySQL DB에 들어있는 데이터를 csv 파일로 변환하는 작업을 설명하겠습니다. 파이돌이님의 블로그 글을 참고했습니다.(파이돌이님의 경우, MySQL이 아닌 mariadb를 예제로 했습니다만 DB에 상관없이 잘 적용됩니다)

코드를 작성하기 앞서 pymysql을 설치해주시길 바랍니다. 

pip install pymysql 
import pandas as pd
import pymysql
# from datetime import datetime

# print('start-time: ', str(datetime.now())[:19])

conn = pymysql.connect(host=' ', user=' ', password=' ', db=' ', charset='utf8')
query = 'select * from medchat_app_tbl_medicine_info'

df = pd.read_sql_query(query, conn)
df.to_csv(r'backup.csv', index=False)
# print('end-time: ', str(datetime.now())[:19])

pymysql 모듈을 사용할 때와 판다스를 사용할 때를 비교하는 글이어서 시간을 재는 명령어가 있는데 생략하셔도 됩니다. 코드를 돌리면 해당 코드 파일이 위치한 디렉토리에 csv 파일이 생성될 것입니다. 참고로 저 같은 경우, 오피스 365 엑셀을 사용하면 문자가 다 깨져서 Libreoffice를 주로 사용하는 편입니다. 

728x90
반응형