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 오류 발생