์ต๊ทผ ๊ตฌํํ๊ฒ ๋ ๊ธฐ๋ฅ์ '์ง์ญ ๊ธฐ๋ฐ ๊ฒ์๊ธ ๊ฒ์'์ด๋ค. ๋๋ฌด๋๋ ์ ๋ช ํ ์๋น์ค์ธ ๋น๊ทผ๋ง์ผ์ ํํ๋ฉด์์ ๋ด๊ฐ ์ด๊ณ ์๋ ๋๋ค ๊ทผ์ฒ์ ์๋ ์ค๊ณ ๊ฑฐ๋ ๊ฒ์๊ธ์ ๋ณด๋ ๊ฒ๊ณผ ๋น์ทํ๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค. ๋ด๊ฐ ํ๋ก์ ํธ์์ ๊ตฌํํ๊ฒ ๋ ๊ธฐ๋ฅ๋ ์ฌ์ฉ์๊ฐ ์ ํํ ์ง์ญ์ ๊ทผ์ฒ ์ง์ญ์ ์๋ ๋ชจ๋ ๊ฒ์๊ธ๋ค์ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ด๋ค.
์๋๋ ์ฃผ์๋ฅผ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ๋ค(์ฌ์ฉ์ ์ฃผ์ ๋ฑ๋ก, ๊ณต์ฌ ๋ด์ญ ๋ฑ๋ก)์ ํ๋ก ํธ์๋์์ select box๋ฅผ ํตํด ๋ฒ์ ๋ ๊ธฐ๋ฐ์ผ๋ก ์๋, ์๊ตฐ๊ตฌ, ์๋ช ๋์ ์ ๋ ฅ์ ํ๋ฉด, ์ฃผ์๋ช ์ผ๋ก ์์ฒญ์ด ์์ DB์ ์ฃผ์๋ช ๊ทธ๋๋ก ์ ์ฅํ๋ ๋ฐฉ์์ด์๋ค.
ํ์ง๋ง, '์ง์ญ ๊ธฐ๋ฐ ๊ฒ์ ๊ธฐ๋ฅ'์ด ๋ค์ด๊ฐ๊ฒ ๋๋ฉด์ ํ์ฅ์ฑ์ ์ํด ๋ฐฑ์๋ ์๋ฒ์๋ ๋ฒ์ ๋ ์ฝ๋์ ํจ๊ป ์๋๋ช , ์๊ตฐ๊ตฌ๋ช , ์๋ฉด๋๋ช ์ ์ ์ฅํ ํ์๊ฐ ์์๋ค. ๊ฒ๋ค๊ฐ, '๊ทผ์ฒ ์ง์ญ์ ๊ฒ์๋ฌผ ๊ฒ์'์ด ๋๋ฉด์, ๋ฒ์ ๋ ์ ๋ณด๋ฟ๋ง ์๋๋ผ ๋ฒ์ ๋์ ์ขํ ์ ๋ณด(์๋, ๊ฒฝ๋)๊น์ง ํ์ํ๊ฒ ๋์๋ค...
๊ธฐ๋ฅ ๊ตฌํ์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ป๊ธฐ ์ํด ๋ฐ์ดํฐ ์์ง๊ณผ ๊ฐ๊ณต์ ๋ง์ ๊ณ ๋ฏผ๊ณผ ์๊ฐ์ ์๊ฒ ๋์ด์, ๊ทธ ๊ณผ์ ์ ์ ์ด๋ณด๊ณ ์ ํ๋ค!
1. ๋ฒ์ ๋ ์ฝ๋์ ๋์ด๋ฆ ์ ์ฅํ๊ธฐ -> ํ์ฌ ํฌ์คํ
2. ๋ฒ์ ๋์ ์ขํ๊ฐ(์๋, ๊ฒฝ๋) ์ ์ฅํ๊ธฐ -> ๋ค์ ํฌ์คํ
๊ฐ๋ฐ ํ๊ฒฝ
- OS : MAC M2
- Data : Python3
- IDE : Visual Studio Code
- DB : MySQL 8.0.36
๋ฒ์ ๋ ๋ฐ์ดํฐ ์์งํ๊ธฐ
ํ์ฌ ํ๋ก ํธ์๋(React Native)์์ ์ฐ๊ณ ์๋ JSON ํํ์ ๋ฒ์ ๋ ์ฃผ์ ํ์ผ์ด ์์๋ค. ํ์ง๋ง, ์ ์ฅ๋ ์ฃผ์๊ฐ ๊ณ์ธตํ๋์ด ์์ด ๋ณต์กํด DB์ ์ ์ฅํ๊ธฐ์๋ ์ด๋ ค์๋ณด์๋ค.
๊ทธ๋์ XLSX(์์ )์ด๋ SCV ํ์ผ์ ๊ตฌํด์ ์ง์ ๊ฐ๊ณตํ๊ธฐ๋ก ํ๋ค. ํ์ผ์ ์ด์ฉํ๋ฉด ๋ฒ์ ๋ ์ฝ๋, ์๋๋ช , ์๊ตฐ๊ตฌ๋ช , ์๋ช ๋๋ช ์ ์ค(row) ๋จ์๋ก ๊ฐ์ ธ์ ๊ทธ๋๋ก DB์ ์ ์ฅํ๊ธฐ ์ข๊ธฐ ๋๋ฌธ์ด๋ค.
๊ฒ์์ ํตํด ์ ๋ถ ๊ธฐ๊ด์์ ๊ณต๊ฐํ ๋ฒ์ ๋ ๋ฐ์ดํฐ ํ์ผ์ ์ฐพ์ ์ ์์๋ค.
- ํ์ ์์ ๋ถ(2024.02.08 ๋ฑ๋ก ๋ฒ์ ) : https://www.mois.go.kr/frt/bbs/type001/commonSelectBoardArticle.do?bbsId=BBSMSTR_000000000052&nttId=107074
- jscode20240228.zip ํ์ผ์ ๋ค์ด๋ฐ์ผ๋ฉด, ๋ค์ํ ๋ฒ์ ์ xlsx(์์ ํ์ผ)์ด ์๋ค. ํ์ผ๋ง๋ค ์ป์ ์ ์๋ ์์ธ ์ ๋ณด๊ฐ ๋ค๋ฅด๋ค.
- ๋๋ ๋ฒ์ ๋์ ์ฃผ์๋ช ๋ง ํ์ํ๊ธฐ ๋๋ฌธ์ KIKcd_B.20240208.xlsx์ ์ฌ์ฉํ๋ค.
- ๊ณต๊ณต๋ฐ์ดํฐํฌํธ(2024.05.13 ์์ ๋ฒ์ ) : https://www.data.go.kr/data/15063424/fileData.do
- csv ํํ์ ํ์ผ์ ๋ค์ด๋ฐ์ ์ ์๋ค.
๋ฒ์ ๋ ๋ฐ์ดํฐ ๊ฐ๊ณตํ๊ธฐ
๋ฐฉ๋ฒ1) XLSX ํ์ผ์ SQL ์ฟผ๋ฆฌ๋ก ๋ฐ๊ฟ์ DB์ ์ ์ฅํ๊ธฐ
XLSX์ด๋ SCV ํ์ผ์ ํ์ด์ฌ์์ ๊ฐ์ ธ์ DB๋ก ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ด ์์๋ค. ํ์ง๋ง, ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ๊ท์ฐฎ์๊ธฐ์.. SQL์ ์ฝ์ ํ๋ ์ฟผ๋ฆฌ๋ก ๋ณํํด ์คํ์ํค๊ณ ์, Exel ํ์ผ์ SQL๋ก ๋ฐ๊ฟ์ฃผ๋ ํ๋ก๊ทธ๋จ์ ์ฌ์ฉํ๊ฒ ๋์๋ค.
๋ฒ์ ๋์ฝ๋, ์๋๋ช , ์๋ฉด๋๋ช ์ ๊ฐ์ ธ์ ์ฝ์ ํ๋๋ก ํ๋ค.
INSERT INTO ADDRESS (ADDRESS_CODE, SIDO, SIGUNGU, EUBMYEONDONG) VALUES ('1100000000', '์์ธํน๋ณ์', '', '');
INSERT INTO ADDRESS (ADDRESS_CODE, SIDO, SIGUNGU, EUBMYEONDONG) VALUES ('1111000000', '์์ธํน๋ณ์', '์ข
๋ก๊ตฌ', '');
INSERT INTO ADDRESS (ADDRESS_CODE, SIDO, SIGUNGU, EUBMYEONDONG) VALUES ('1111010100', '์์ธํน๋ณ์', '์ข
๋ก๊ตฌ', '์ฒญ์ด๋');
INSERT INTO ADDRESS (ADDRESS_CODE, SIDO, SIGUNGU, EUBMYEONDONG) VALUES ('1111010200', '์์ธํน๋ณ์', '์ข
๋ก๊ตฌ', '์ ๊ต๋');
INSERT INTO ADDRESS (ADDRESS_CODE, SIDO, SIGUNGU, EUBMYEONDONG) VALUES ('1111010300', '์์ธํน๋ณ์', '์ข
๋ก๊ตฌ', '๊ถ์ ๋');
INSERT INTO ADDRESS (ADDRESS_CODE, SIDO, SIGUNGU, EUBMYEONDONG) VALUES ('1111010400', '์์ธํน๋ณ์', '์ข
๋ก๊ตฌ', 'ํจ์๋');
ํ์ง๋ง, ์๊ตฐ๊ตฌ๋ช , ์๋ฉด๋๋ช ์ด ๋น์ด์๋ ๊ฒ๋ ํจ๊ป ์ ์ฅ์ด ๋์๋ค. ๋์ค์๋ ์๊ตฐ๊ตฌ๋ช , ์๋ฉด๋๋ช ์ ๋์ค์ ์ถ๊ฐ๋ ์๋, ๊ฒฝ๋๊ฐ null์ธ ๋ฐ์ดํฐ๊ฐ ๊ฝค ์๊ธด๋ค๋ ๊ฒ์ด ๋ฌธ์ ์๋ค. ๋จ์ํ ๋ณํ์ผ๋ก๋ ์ด ๊ฒฝ์ฐ๊ฐ ์ ์ฅ๋์ง ์๊ฒ ์ฒ๋ฆฌํ์ง ๋ชปํ๋ค.
๊ทธ๋ฆฌ๊ณ , ์ขํ ์ ๋ณด๋ ์ ์ฅ์ ํด์ผํ๋๋ฐ, ์ด์ฐจํผ ์ฝ๋๋ฅผ ์์ฑํด API๋ก ์ขํ๋ฅผ ๋ฐ์์ ์ ์ฅํด์ผ ๋ผ์ ํ์ด์ฌ์ผ๋ก ๋๋ฆฌ๊ธฐ๋ก ํ๋ค!
๋ฐฉ๋ฒ2) ํ์ด์ฌ์ผ๋ก ์์ ํ์ผ์ ์ฝ์ด DB์ ์ ์ฅํ๊ธฐ
๊ฒ์์ ํตํด ํ์ด์ฌ์ผ๋ก ์์ฑ๋ ํ์ ๋ ๋ฐ์ดํฐ๋ฅผ MySQL DB์ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์ ์ ์์๋ค. ํ์ด์ฌ์ openpysl๊ณผ pymysql ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด ์์ ํ์ผ์ ์ฝ์ด, mysql์ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ฝ๋๋ฅผ ๋ด ์ก์ ํ์ผ๊ณผ ํ์ํ ๋ฐ์ดํฐ์ ๋ง๊ฒ ์์ ํด DB์ ์ ์ฅํ ์ ์์๋ค.
ํ์ด์ฌ์ผ๋ก ์์ ๋ฐ์ดํฐ DB์ ์ ์ฅํ๊ธฐ
1) ํ์ด์ฌ ํจํค์ง ์ค์นํ๊ธฐ
pip3 install openpyxl
pip3 install pymysql
- openpyxl : ์์ ํ์ผ ์ฌ์ฉ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- pymysql : MySQL ์ฌ์ฉ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
*์ฃผ์ : ๋งฅ์์๋ pip ๋ง๊ณ , pip3๋ผ๊ณ ๋ช ์๋ฅผ ํด์ค์ผ ์คํ์ด ๋๋ค. ๋ง์ฝ, pip3 ๋ช ๋ น์ด๋ ์๋จนํ๋ค๋ฉด, ์ค์ ์ ๋ฐ๋ก ๋ ํด์ค์ผ ํ๋ค!
python3 -m pip config set global.break-system-packages true
2) ์์ ํ์ผ ๋ถ๋ฌ์์ ์ฝ๊ธฐ
๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋, ๊ณ ๋ คํด์ผ ๋ ๋ถ๋ถ์ด ์์๋ค.
- ์๊ตฐ๊ตฌ๋ช , ์๋ช ๋๋ช ์ด ๋น์ด์๋ ์ค์ ์ ์ฅํ์ง ์๋๋ค.
- ๋๋ฆฌ๋ช ๋จ์๊น์ง๋ ํ์ํ์ง ์์ผ๋ฏ๋ก ์ ์ฅํ์ง ์๋๋ค. (์ฌ๊ธฐ์ ์ฃผ์ํ๊ธฐ)
์์ ๊ฒฝ์ฐ์ฒ๋ผ, ์๋จ์์์๋ ๋ฆฌ๊น์ง ์กด์ฌํ๋ค. ๊ทธ๋์ ๋๋ฆฌ๋ช ์ด null์ธ ๊ฒฝ์ฐ์๋ง ์ ์ฅ์ ํ๋๋ก ํ๋ค.
from openpyxl import load_workbook
import pymysql
mydict = {}
def import_xlsxfile(filename):
load_wb = load_workbook(filename, data_only=True)
load_ws = load_wb['KIKcd_B']
head = True
for row in load_ws.rows:
if head is True:
head = False
continue
if row[2].value is None or row[3].value is None:
continue
if not row[4].value: #๋๋ฆฌ๋ช
๊น์ง ์ถ๋ ฅ ์ํจ
fullCode = row[0].value # A = row[0] ๋ฒ์ ๋์ฝ๋
sido = row[1].value # B = row[1] ์๋๋ช
sigungu = row[2].value # C = row[2] ์๊ตฐ๊ตฌ๋ช
eubmyeondong = row[3].value # D = row[3] ์๋ฉด๋๋ช
mydict[fullCode] = [fullCode, sido, sigungu, eubmyeondong]
2) MySQL์ ์ ์ฅํ๊ธฐ
MySQL์ ๋จผ์ ํ ์ด๋ธ์ ์์ฑํด์ฃผ์๋ค.
๊ทธ๋ฆฌ๊ณ MySQL์ ์ฐ๊ฒฐํ์ฌ, ์์ Dictionary์ ์ ์ฅํ ๊ฐ๋ค์ DB์ ๋ฃ์๋ค.
def insert_into_mysql():
conn = pymysql.connect(host='ํธ์คํธ ์ฃผ์', user='๊ณ์ ๋ช
', password='๋น๋ฐ๋ฒํธ', db='DB๋ช
', charset='utf8')
curs = conn.cursor()
for key in mydict:
arr = mydict[key]
sql = "INSERT INTO address VALUES(\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\");"\
% (arr[0], arr[1], arr[2], arr[3], arr[4], arr[5])
curs.execute(sql)
conn.commit()
conn.close()
4) ์คํ ๊ฒฐ๊ณผ
์ฐธ๊ณ ์๋ฃ
[Python] ๋ํ๋ฏผ๊ตญ ํ์ ๋ ๋ฐ์ดํฐ MySQL DB ํ ์ด๋ธ ์์ฑ ์์ : https://woonizzooni.tistory.com/entry/Python-%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD-%ED%96%89%EC%A0%95%EB%8F%99-%EB%8D%B0%EC%9D%B4%ED%84%B0-MySQL-DB-%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%83%9D%EC%84%B1-%EC%98%88%EC%8B%9C