CODE_DETAIL
테이블에 데이터를 적재하기 위해 csv
파일로 만드는 과정에서 이전 모델링에서 문제가 있다는 것을 발견했다.TOUR API
를 직접 조회해 보기 전에는 알지 못했던 부분인데 고유의 값인 줄 알았던 CITY_CODE
즉, API에서는 SIGUNGUCODE
가 고유의 값이 아니라 AREA_CODE
와 연관되어 있었고, 중복이 발생할 수도 있다는 부분이었다.AREA_CODE
가 1이면 서울, 2면 인천인데 CITY_CODE
가 AREA_CODE=1
의 경우 1이 강남구였고, AREA_CODE=1
의 경우 1이 강화군이었다. CITY_CODE
는 고유의 값이 될 수 없었고, 테이블 구성 역시 바꿔야 했다.CITY_CODE
에 서로 중복이 없을 거라 생각했기 때문에 CODE_CATEGORY
로 구분을 두면 되겠다고 생각했는데 만약 이 구조로 가게 된다면 CODE = 1 AND CODE_CATEGORY = 1
인 데이터가 특별시, 광역시, 특별자치시, 도마다 하나씩 존재하기 때문에 pk 오류가 발생할 수밖에 없어 다음과 같이 수정해 주었다.SEQ
를 통해 중복이 발생하지 않고 각 CODE의 고유 값이 생기게 해 주었다.CITY_CODE
는 각각 AREA_CODE
에 종속돼 있기 때문에 AREA_CODE
가 일종의 부모 개념이라고 생각되어 PARENT_CODE
컬럼을 추가해 주었다. CITY_CODE
와 AREA_CODE
가 같이 들어 있던 부분도 CODE_SEQ
라는 하나의 값으로 변경되게 되었다.📌 최종 ERD
AREA_CODE
에 속해 있는 각각 도시의 CITY_CODE
를 조회해야 했기 때문에 다음과 같은 URL을 사용해 주었다. API_KEY
가 ENCODING
과 DECODING
버전 두 개가 있는데 어떤 KEY를 주어야 할지가 헷갈렸다. DECODING
버전을 파라미터로 넘겨 주면 된다.import urllib
import json
from pprint import pprint
import requests
import pprint
key = '발급받은 api_key'
url = 'http://apis.data.go.kr/B551011/KorService1/areaCode1' #호출할 서비스의 url
requests.get
을 통해 url과 함께 넘겨 주었다.params ={'serviceKey' : decoding ,
'pageNo' : '1',
'numOfRows' : '100',
'MobileOS' : 'ETC',
'MobileApp' : 'AppTest',
'areaCode' : 1
}
response = requests.get(url, params=params)
seoul_content = response.text
seoul = pprint.PrettyPrinter(indent=4)
print(seoul.pprint(seoul_content))
xml
파일이 나오게 되고, 나는 CITY_CODE
를 쌓아 주어야 해서 모든 AREA_CODE
별로 추출해 주었다.AREA_CODE
별로 리스트에 추가해 주어야 했다.pandas
를 통해 DataFrame
으로 만들어 준다.from os import name
import xml.etree.ElementTree as et
import pandas as pd
import bs4
from lxml import html
from urllib.parse import urlencode, quote_plus, unquote
xml_obj = bs4.BeautifulSoup(seoul_content,'lxml-xml')
rows = xml_obj.findAll('item')
row_list = [] # 행값
name_list = ["CODE", "CODE_CATEGORY", "CODE_NM", "PARENT_CODE"] # 열이름값
value_list = [] #데이터값
# 서울
for i in range(0, len(rows)):
columns = rows[i].find_all()
#첫째 행 데이터 수집
for j in range(0,len(name_list)):
if j == 0:
value_list.append(columns[1].text)
elif j == 1:
value_list.append("CITY")
elif j == 2:
value_list.append(columns[2].text)
else:
value_list.append("1")
# 각 행의 value값 전체 저장
row_list.append(value_list)
# 데이터 리스트 값 초기화
value_list=[]
df = pd.DataFrame(row_list, columns=name_list)
df
df.to_csv('city.csv', encoding='utf-8-sig')
로 csv 파일로 추출해 주었다.사용자 행동 데이터 수집
사용자 세분화(User Segment)
퍼널 데이터
코호트 분석
A/B 테스트
사용자 리텐션 분석
데이터 시각화 및 리포트 생성
다른 툴과의 통합 기능 제공
데이터 웨어하우스
에 적재하는 것이 아닌 데이터 레이크
에 저장해 두고 필요 시 가공하여 데이터 웨어하우스에 적재한다.📌 마케팅 접점 데이터 레이어
- 마케팅 접점 데이터 수집 레이어
- 마케팅 접점 데이터와 고객/전환 데이터 저장 레이어
- 마케팅 접점 데이터 분석/시각화 레이어
- 채널별 마케팅 비용
ROAS(Return On Advertising Spend) 시 필요
두 가지 방법으로 다음과 같이 마케팅 접점 데이터 저장 (ETL)을 해 줌
- SaaS (FiveTran, Stitch Data, Segment 등의 툴)을 사용하는 방법
- 직접 ETL을 구현하는 방법
📌 SEQ를 지원하지 않는 REDSHIFT
- Redshift는
SEQ
기능을 지원하지 않았다. 사실SEQ
를 사용하는 게 중복이 발생하지 않게 하는 데 좋을 것이라는 생각에 CREATE를 할 때 컬럼에 default 속성으로NEXTVAL
를 부여하려고 했는데 REDSHIFT에는 지원하지 않는 기능이라고 했다.- 물론
PostgreSQL
에서 지원하지 않는 기능은 아니다.SEQ
기능은PostgreSQL
에서는 지원하지만REDSHIFT
에서 지원하지 않을 뿐이다.- 그래서 csv 자체에서 SEQ를 추가해 주어야만 했다.
📌 Bulk Update 시 unsupported UTF8 오류 발생
- 처음 알게 된
SQL
옵션이 있어서 따로 포스팅 해 두었다.- 🔑 csv 파일 벌크 업데이트 시 invaild or unsupported UTF8 오류 발생