qcoding

4) Excel 파일로 JSON 형태 변경 및 Firebase 데이터 저장 본문

[사이드 프로젝트]App개발 - 전국 국밥 찾기

4) Excel 파일로 JSON 형태 변경 및 Firebase 데이터 저장

Qcoding 2022. 1. 14. 15:51
반응형

- 목적

-> 지난 글에서 python webscraping을 통해 만든 excel 파일를 DB형태로 사용하려면 <XML> 또는 <JSON> 의 형태로 변경해야한다. 앞선 글에서 FireBase를 당장은 사용하지 않지만 후에 사용할 수도 있어서 FireStore를 사용해보았다.

 

- 방법

-> 1) Python을 통한 excel to Json 변경 , 아래의 라이브러리 사용

import json
from collections import OrderedDict
from openpyxl import load_workbook

우선 파일 변경을 하기전 내가 원하는 json형태를 선정한다. 내가 생각한 data의 형태는 아래와 같이 key로 각 지역별 정보를 가져올 수 있고, value에는 Array [  ] ( = list ) 형태로 되어 있어서 후에 ReactNative로 App을 만들 때 각 음식점 정보를 불러올 수 있도록 선정하였다.

{
	"서울국밥":[
    	{각 음식점별 정보},
        {각 음식점별 정보},
    ],
    
    "경기국밥":[
    	{각 음식점별 정보},
        {각 음식점별 정보},
    ]
	...
}

위와 같은 형태를 만들기 위하여 아래의 코드를 작성하였다. 아래 코드를 살펴보면 알 수 있겠지만 여기서

OrderedDict() 함수를 이용하게 되면 { } 의 Dictionary (= Object ) 를 생성한다. 엑셀파일에서 필요한 정보를 불러와서 배열로 만든다음 지역별 이름을 key값으로 사용하고 value에는 생성된 배열을 넣어준다.

 

* excel to Json 변경 코드

import json
from collections import OrderedDict
from openpyxl import load_workbook


# data_only=True로 해줘야 수식이 아닌 값으로 받아온다.
load_wb = load_workbook("전국국밥.xlsx", data_only=True)

array = ["서울국밥", "경기국밥", "강원국밥", "충청국밥", "전라국밥", "경상국밥", "제주국밥"]
# Ready for data
group_data = OrderedDict()

for sheet in array:
    print(f"*************************************{sheet}**************")
    # 시트 이름으로 불러오기
    load_ws = load_wb[sheet]

    # 모든 행/열 다 불러오기
    all_values = []
    id = -1
    # 지역별로 array 내에 담기 위해서 temp_arr를 초기화 시켜준다.
    temp_arr = []
    for row in load_ws.rows:
        row_value = []
        id += 1
        for cell in row:
            row_value.append(cell.value)
        temp_arr.append({
            "diningCode_url": row_value[0],
            "score": row_value[1],
            "name": row_value[2],
            "recommend_food": row_value[3],
            "keyword": row_value[4],
            "dong": row_value[5],
            "address": row_value[6],
            "lat": row_value[7],
            "lon": row_value[8],
            "img_url": row_value[9],
        })
        # 위에서 만든 collention을 상위 collention에 넣음
        group_data[sheet] = temp_arr

print(json.dumps(group_data, ensure_ascii=False, indent="\t"))
# Write JSON
with open('food_info.json', 'w', encoding="utf-8") as make_file:
    json.dump(group_data, make_file, ensure_ascii=False, indent="\t")

*최종 완성 Json 형태 (food_info.json파일)

 

-> 2) Python을 통한 FireStore upload 

import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
from openpyxl import load_workbook

위의 라이브러리를 사용하며, 여기서 firebase 를 python으로 업데이트 하는 법은 google을 찾아보면 많이 나오므로 따로 설명하진 않으려고 한다.

현재 아래의 코드 역시 위의 json 형태와 동일하게 firebase에 저장이 되게 된다. 이때 데이터의 저장형태에 대한 Firebase 함수로 좀 헤맨 부분이 있는데, set 과 update의 차이이다. 

우선 set을 하게 되면 덮어쓰게 되서 최종적으로 마지막 음식점 값만 남게 되었다. 반면에 update를 하게되면 계속 추가가 되서 내가 생각하는 json형태가 얻어지게 되었다.

Firebase&nbsp;데이터 저장 방법
FireStore 확인

최종적으로 아래의 코드를 돌리게 되면 위와 같이 FireStore에 업데이트 된다.

현재 App에서는 위의 FireStore에서 데이터를 사용하지는 않고, json 파일에서 가져와서 사용하고 있다.

 

*Firebase Upload 코드

import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
from openpyxl import load_workbook

cred = credentials.Certificate("upload.json")
firebase_admin.initialize_app(cred)

db_client = firestore.client()

# data_only=True로 해줘야 수식이 아닌 값으로 받아온다.
load_wb = load_workbook("전국국밥_수정.xlsx", data_only=True)
# 시트 이름으로 불러오기
load_ws = load_wb['서울국밥']

# 모든 행/열 다 불러오기
all_values = []
for row in load_ws.rows:
    row_value = []
    for cell in row:
        row_value.append(cell.value) 
    # db 아래에 바로 document 아래에 넣는것
    # 구분 할 것 set을 하게 되면 기존값이 있으면 대체가 되고
    # update를 하게 되면 대체가 아닌 추가가 된다고 생각하면됨
    db_client.collection("food").document('seoul').update({
        row_value[2]:
        {
        "diningCode_url": row_value[0],
        "score": row_value[1],
        "name": row_value[2],
        "recommend_food": row_value[3],
        "keyword": row_value[4],
        "dong": row_value[5],
        "address": row_value[6],
        "lat": row_value[7],
        "lon": row_value[8],
        "img_url": row_value[9]
    }     
    })

    # db 아래에 바로 document에넣는 것
    # db_client.collection("food").add({
    #     "diningCode_url":row_value[0],
    #     "score":row_value[1],
    #     "name":row_value[2],
    #     "recommend_food":row_value[3],
    #     "keyword":row_value[4],
    #     "dong":row_value[5],
    #     "address":row_value[6],
    #     "lat":row_value[7],
    #     "lon":row_value[8],
    #     "img_url":row_value[9]
    # })
반응형
Comments