CSV를 활용한 DB 데이터 업로드

seinthemag·2022년 1월 5일
0

TIL

목록 보기
2/2

CSV란?

CSV(comma-separated values)는 몇 가지 필드를 쉼표(,)로 구분한 텍스트 데이터 및 텍스트 파일로서, 확장자는 .csv이다.

CSV 작성법

.csv 확장자의 파일을 만들어 ,로 구분지어 직접 작성하거나 스프레드시트, 넘버스와 같은 셸 작성 프로그램에서 표 형태로 작성후 .csv확장자로 저장하는 방법 등이 있다. 개인적으로 작성 시 가독성 면에서 후자가 더 편한 것 같다.

예시)

1. 엑셀 형태의 프로그램을 이용해 표에 데이터를 넣어준다.


2. csv 파일로 추출하여 VS Code로 불러온다.

tip. VS Code의 rainbow csv 확장 프로그램을 설치하면 사진처럼 , 단위로 텍스트 컬러를 바꿔서 출력해주기 때문에 가독성이 매우 향상된다.

CSV를 사용하는 이유

만약 넣어야 할 데이터가 5개 밖에 안된다면 굳이 CSV파일을 따로 작성하고, 또 그 CSV파일을 DB table에 업로드시킬 함수를 또 작성하는 것보다는 그냥 python manage.py shell을 활용해 objects.create형태로 업로드 하는 것이 나을 수도 있다.

하지만 한 서비스에서 데이터가 5~6개만 있는 경우는 거의 없을 것이다. 어떤 서비스의 판매상품이 5000개라고 가정해보자. shell을 이용해 하나하나 생성하면 정말 하루종일 python shell만 쳐다보며 같은 명령어를 반복하는 작업을 해야 할 것이다. 또 예기치 못한 문제로 테이블이 통째로 날아갔다고 상상해보자. 또다시 5000개의 상품을 입력하기 위해 shell을 붙들어매고 있어야 할 것이다.

하지만 CSV를 이용하면 데이터를 한번에 집어넣을 수 있기 때문에 이러한 수고를 덜어줄 수 있다.

db_uploader.py 작성하기

CSV 파일에 데이터를 집어넣었다고 해서 그 데이터들이 자동으로 실제 DB에 저장되지는 않는다. 이 단계는 CSV파일의 데이터들을 실제 DB에 밀어넣기 위한 로직을 작성하는 단계이다.

새로운 py 파일을 생성해 내용을 작성하자. 파일명은 되도록 용도를 알 수 있도록 db_uploader.py라는 이름으로 정했다.

#임포트
import os
import sys
import csv
import django

#환경변수 세팅(뒷부분은 프로젝트명.settings로 설정한다.)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MotherTerarosa.settings")
django.setup()

# model import
from products.models import *

#읽어들일 csv 디렉토리를 각 변수에 담는다.
MENU_PATH         = './csv/Menus.csv'
CATEGORIES_PATH   = './csv/Categories.csv'
PRODUCT_PATH      = './csv/Products.csv'
TASTINGNOTES_PATH = './csv/Tasting_notes.csv'
IMAGES_PATH       = './csv/Images.csv'
PRODUCTTASTINGNOTES_PATH = './csv/Product_Tasting_notes.csv'

#함수 정의하기 (row부분엔 해당 table의 row명을 적어준다.)
def insert_Menu():
    with open(MENU_PATH) as csv_file:
        data_reader = csv.reader(csv_file)
        next(data_reader, None)
        for row in data_reader:
            if row[0]:
                name = row[0]
                print(name)
                Menu.objects.create(name = name)
    print('MENU DATA UPLOADED SUCCESSFULY!')
#print 부분은 터미널에서 파일을 실행했을때 데이터 입력이 잘 되었는지 확인하는 용도로써 필수요소는 아니다.


def insert_Category():
    with open(CATEGORIES_PATH) as csv_file:
        data_reader = csv.reader(csv_file)
        next(data_reader, None)
        for row in data_reader:
            if row[0]:
                name    = row[0]
                menu_id = row[1]
                print(name, menu_id)
                Category.objects.create(name = name, menu_id = menu_id)
    print('CATEGORY DATA UPLOADED SUCCESSFULY!')

def insert_Product():
    with open(PRODUCT_PATH) as csv_file:
        data_reader = csv.reader(csv_file)
        next(data_reader, None)
        for row in data_reader:
            if row[0]:
                name                = row[0]
                price               = row[1]
                description         = row[2]
                thumbnail_image_url = row[3]
                product_hits        = row[4]
                menu_id             = row[5]
                category_id         = row[6] or None
                print(name, price, description, thumbnail_image_url, product_hits, menu_id, category_id)
                Product.objects.create(
                    name = name,
                    price = price,
                    description = description,
                    thumbnail_image_url = thumbnail_image_url,
                    product_hits = product_hits,
                    menu_id = menu_id,
                    category_id = category_id
                    )
    print('PRODUCT DATA UPLOADED SUCCESSFULY!')

def insert_TastingNote():
    with open(TASTINGNOTES_PATH) as csv_file:
        data_reader = csv.reader(csv_file)
        next(data_reader, None)
        for row in data_reader:
            if row[0]:
                name = row[0]
                print(name)
                TastingNote.objects.create(name = name)
    print('TASTINGNOTE DATA UPLOADED SUCCESSFULY!')

def insert_Image():
    with open(IMAGES_PATH) as csv_file:
        data_reader = csv.reader(csv_file)
        next(data_reader, None)
        for row in data_reader:
            if row[0]:
                image_url  = row[0]
                product_id = row[1]
                print(image_url, product_id)
                Image.objects.create(image_url = image_url, product_id = product_id)
    print('IMAGE DATA UPLOADED SUCCESSFULY!')

def insert_ProductTastingNote():
    with open(PRODUCTTASTINGNOTES_PATH) as csv_file:
        data_reader = csv.reader(csv_file)
        next(data_reader, None)
        for row in data_reader:
            if row[0]:
                product_id = row[0]
                tasting_notes_id = row[1]
                print(row[0], row[1])
                
                product = Product.objects.filter(id=product_id).first()
                tasting_note = TastingNote.objects.filter(id=tasting_notes_id).first()
                product.tasting_notes.add(tasting_note)          
    print('PRODUCTTASTINGNOTE DATA UPLOADED SUCCESSFULY!')



# 함수 실행
insert_Menu()
insert_Category()
insert_Product()
insert_TastingNote()
insert_Image()
insert_ProductTastingNote()    

실행 및 DB확인

db_uploader.py 작성이 완료되었다면 터미널을 실행하고 해당 경로로 들어가 python db_uploader.py 명령어를 통해 파일을 실행시킨다.

print를 찍었기에 해당 데이터들이 print되는 모습을 볼 수 있다.

mysql에 접속해서 해당 DB의 table을 조회해보면 이렇게 데이터가 잘 입력된 것을 확인할 수 있다.

0개의 댓글