[Database] CSV와 Python

SungjoonAn·2022년 3월 6일
0

파이썬

목록 보기
6/6
post-thumbnail

CSV

CSV(Comma Seperated Value) 란 데이터는 쉼표를 기준으로 항목을 구분하여 저장하는 데이터를 말합니다. 콤마로 규칙적으로 구분되어 있기 때문에 엑셀과 같은 프로그램으로도 읽을 수 있고, 또 생성할 수도 있습니다. 주로 테이블 형태로 구성된 자료텍스트 자료를 저장할 때 사용합니다.

데이터의 크기가 작고, 많은 애플리케이션에서 활용할 수 있는 범용 형식이기 때문에 자료를 주고 받아야 하는 다양한 상황에서 CSV형식을 사용합니다. 같은 데이터를 저장한다고 했을 때, JSON 데이터에 비하여 절반 이하의 용량으로 저장할 수 있습니다.

쉼표를 대신하여 다른 문자 ($, %, etc.)를 이용하여 구분하도록 지정할 수도 있습니다. 예를 들어 데이터 자체에 쉼표가 포함되어 있을 경우 다른 기호로 대체하여 사용합니다.

CSV 파일의 한 줄 한 줄이 행(row) 한 개가 되고, 열(column) 사이에는 쉼표를 넣어 구분합니다. 한 열을 필드(field)라고 부르기도 합니다.

weight,caffeine,price,name,farm_name,farm_image,category_name,drink_image,rating,comment,email,password,username,point,address,quantity
23,2,2000,인삼차,보령농장,www.1234.com,뿌리차,www.drinkimage.com,4,핵존맛,1park2@daum.com,qlalfqjsgh@1,영서,,주소1,10
33,3,3000,옥수수수염차,울산농장,www.2345.com,뿌리차,www.drinkimage.com,5,맛있어요,1park3@daum.com,qlalfqjsgh@2,영선,,주소2,20
44,4,4000,깻잎차,깻잎농장,www.3456.com,잎사귀차,www.drinkimage.com,3,그냥그럼,1park4@daum.com,qlalfqjsgh@3,영석,,주소3,30
55,0,5000,마차,마산농장,www.5678.com,줄기차,www.drinkimage.com,2,별로에요,1park5@daum.com,qlalfqjsgh@4,영숙,,주소4,40

weight, caffeine, price, name, 등 16개 필드가 있습니다. 이 파일을 mac의 numbers나 윈도우의 엑셀을 이용해 열면 엑셀과 같은 형식의 데이터가 나타납니다.

CSV file 생성

빈 파일을 연다.
콤마로 구분된 데이터를 입력한다.
.csv 확장자로 저장한다.

csv 파일은 엑셀 파일처럼 만드는 사람의 의도에 따라 자유자재로 만들 수 있습니다.

예시 1 | 메뉴, 카테고리, 제품 이름을 모두 나열

menu,category,product
음료,콜드 브루 커피,나이트로 바닐라 크림
음료,콜드 브루 커피,제주 비자림 콜드
음료,콜드 브루 커피,코코넛 화이트 콜드 브루
음료,콜드 브루 커피,나이트로 쇼콜라 클라우드
음료,콜드 브루 커피,콜드 브루 몰트
음료,브루드 커피,아이스 커피
음료,브루드 커피,오늘의 커피
음료,에스프레소,에스프레소 콘 파나
음료,에스프레소,에스프레소 마키아또
음료,에스프레소,카페 아메리카노
음료,프라푸치노,더블 에스프레소 칩 프라푸치노
음료,프라푸치노,블랙 와플칩 크림 프라푸치노
음료,프라푸치노,피스타치오 크림 프라푸치노 

첫번째 텍스트는 CSV 파일을 일반 에디터 (vim or vscode)로 열었을 경우이고, 아래 이미지는 CSV 파일을 numbers 또는 excel 로 열었을 경우입니다. 이렇게 만든 후 starbucks.csv 라는 이름으로 저장하시면 파로 csv 데이터가 됩니다.

예시 2 | 중복된 메뉴, 카테고리는 한 번만 나열

예시 1에서 음료 라는 메뉴 이름과 콜드 브루 커피, 브루드 커피, 에스프레소, 프라푸치노 를 여러번 사용하지 않고 한 번만 넣고 싶을 수 있습니다. 값이 없어도 콤마(,)만 있다면 분리된 칸으로 인식하기 때문에 값을 비워두고 싶을 경우 아무것도 입력하지 않고 콤마로 분리해주시면 됩니다. 왼쪽처럼 작성할 경우, 오른쪽과 같은 파일입니다.

menu,category,product
음료,콜드 브루 커피,나이트로 바닐라 크림
,,제주 비자림 콜드
,,코코넛 화이트 콜드 브루
,,나이트로 쇼콜라 클라우드
,,콜드 브루 몰트
,브루드 커피,아이스 커피
,,오늘의 커피
,에스프레소,에스프레소 콘 파나
,,에스프레소 마키아또
,,카페 아메리카노
,프라푸치노,더블 에스프레소 칩 프라푸치노
,,블랙 와플칩 크림 프라푸치노
,,피스타치오 크림 프라푸치노

Python을 통해 CSV 읽기

대부분의 프로그래밍 언어가 텍스트 파일을 읽을 수 있습니다. 특히 Python에는 CSV 파일을 다루기 위한 모듈이 있습니다. 그 가운데 csv.reader( ) 또는 csv.DictRedader( )라는 method를 이용하면 쉽게 .csv 파일을 다룰 수 있습니다.

Python에서 with open (file_name) as (file_name): 구문을 이용하면 외부 파일을 연 상태로 작업합니다. csv.reader 메소드를 이용하면 파일 내부의 모든 행을 rows이라는 변수에 담을 수 있습니다. 모든 행을 한 줄 한 줄 읽으면서 작업을 수행하기 위해서 for 문을 활용합니다.

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "chadamhwa.settings")
import django
django.setup()
import csv #csv파일을 다루기 위한 라이브러리를 import 합니다.

from drinks.models import *
from users.models import *
from orders.models import *
CSV_PATH = './sample.csv' #csv 경로

def insert_images():
    with open(CSV_PATH) as in_file:
        data_reader = csv.DictReader(in_file)
        for row in data_reader:
            if row["drink_image"] != "":
                if not DrinkImage.objects.filter(image_url=row["drink_image"]).exists():
                    DrinkImage.objects.create(image_url=row["drink_image"])

def insert_categories():   
    with open(CSV_PATH) as in_file:
        data_reader = csv.DictReader(in_file)
        for row in data_reader:
            if row["category_name"] != "":
                if not Category.objects.filter(name=row["category_name"]).exists():
                    Category.objects.create(name=row["category_name"])

def insert_farms():
    with open(CSV_PATH) as in_file:
        data_reader = csv.DictReader(in_file)
        for row in data_reader:
            if row["farm_name"] and row["farm_image"] != "":
                if not Farm.objects.filter(name=row["farm_name"]).exists():
                    Farm.objects.create(name=row["farm_name"], image_url=row["farm_image"])

def insert_drinks():
    with open(CSV_PATH) as in_file:
        data_reader = csv.DictReader(in_file)
        for row in data_reader:
            if row["category_name"]:
                category = Category.objects.get(name=row["category_name"])
            if row["farm_name"]:
                 farm = Farm.objects.get(name=row["farm_name"])
            if row["weight"] and row["caffeine"] and row["price"] and row["name"] != "":
                if not Drink.objects.filter(name=row["name"]).exists():
                    image = DrinkImage.objects.get(image_url=row["drink_image"])             
                    Drink.objects.create(
                        category = category, 
                        image = image,
                        farm = farm,
                        weight=row["weight"],
                        caffeine=row["caffeine"],
                        price=row["price"],
                        name=row["name"])

def insert_users():
    with open(CSV_PATH) as in_file:
        data_reader = csv.DictReader(in_file)
        for row in data_reader:
            if row["username"] and row["email"] and row["password"] and row["address"] != "":
                if not User.objects.filter(email=row["email"]).exists():
                    User.objects.create(
                        username = row["username"],
                        email = row["email"],
                        password = row["password"],
                        address = row["address"]
                    )

def insert_reviews():
    with open(CSV_PATH) as in_file:
        data_reader = csv.DictReader(in_file)
        for row in data_reader:
            if row["rating"] and row["comment"] != "":
                user = User.objects.get(username=row["username"])
                drink = Drink.objects.get(name=row["name"])  
                Review.objects.create(
                    drink = drink,
                    user = user,
                    rating= row["rating"],
                    comment = row["comment"],
                )

insert_images()
insert_categories()
insert_farms()
insert_drinks()
insert_users()
insert_reviews()

0개의 댓글