안녕하세요. 오늘은 이번에 TEST DB에서 저희가 개발해놓은 운영 DB로 옮기는 과정에서 생긴 오류에 대해서 포스팅하겠습니다! 일단 간단히 말씀드리면, TEST DB에서 테이블 간의 관계를 생각하지 않고, DAG를 짰고 그 과정에서 SPOTIFY API의 특성을 생각하지 못했던 점이였습니다 ㅜㅜ.
SPOTIFY API
글로벌TOP50 트랙(매일 업데이트)을 뽑고, 그 트랙 속에서 아티스트를 추출하고나서, 아티스트의 HOT TRACK 10곡을 뽑아서, 트랙 세부 정보와 트랙 오디오 세부 정보를 뽑는 DAG였습니다. 그런데 아티스트의 HOT TRACK 10곡을 뽑는 API에서, 조회한 ARTIST의 HOT TRACK에는 아티스트가 피처링으로 참여한 곡도 포함되어있었습니다. 그러다보니, 곡의 세부 정보를 봅은 데이터에서, ARTIST_ID가 제가 조회하려고 한 아티스트 외에 다른 아티스트도 포함되어있었던 겁니다.
TEST DATABASE의 관계를 정의하지 않아서 생긴 실수
위에 저런 상황을 모르고 있었던 저는, 테이블 간의 관계를 정의하지 않은 테스트 테이블에서 작업할 땐 잘된다고 좋아했다가,,, 장고 운영 DB로 쓰고 있던 테이블에 들어갈 때 생기는 오류를 예측하지 못했습니다..
그래서 일단 DAG를 최대한 많이 안건드는 쪽에서, 오류를 수정해볼 방법을 고민해봤는데 가장 적절한 트러블 슈팅 방법은 API로 데이터 추출할 때, ARTIST의 피처링 곡을 제거해서 추출하는 방식으로 진행하게 되었습니다. 가장 간단하면서도, 빠르게 해결하는 방법이긴 하지만, ARTIST의 핫 트랙 10곡 중 1 ~ 2곡을 날려야하는게 조금 아쉽긴 합니다. 이렇게 데이터가 연관 관계를 조금 복잡한 방식으로 맺을 때는 NOSQL을 활용해야하나 싶긴 합니다..,
일단 이 프로젝트를 성공적으로 마무리하는게 목표이기 때문에, 간단하게 DAG 중 TASK 일부를 수정했습니다.
## 전 artist를 조회하기 위한 반복문
for artist in artists:
artist_id = artist['id']
artist_name = artist['name']
logging.info(f'######## {artist_name} extract start')
params = {'country' : 'US'}
result = extract('Artist_toptrack', artist_id, headers, params = params)
# 변수 artist_id의 값과 'id' 키의 값이 일치하지 않는 항목 제거
# artist_id의 top_track을 뽑으면 artist가 피처링으로 참여한 곡도 나와서, 다른 artist_id를 가져옴
# 데이터베이스에 데이터를 넣을 때, 참조 무결성 제약조건 어김
result['tracks'] = [track for track in result['tracks'] if track['album']['artists'][0]['id'] == artist_id]
for track in result['tracks']:
track_id = track['id']
# track json Update
track_info = extract('Track', track_id, headers)
tracks.append(track_info)
logging.info(f'#### {artist_name} {track_id} extract track success')
# audio json Update
audio_info = extract('Audio', track_id, headers)
audio.append(audio_info)
logging.info(f'#### {artist_name} {track_id} extract audio success')
중간에 주석 세 줄이 붙어있는 코드인데, JSON에서 ARTISTS의 0번 ID가 제가 변수로 지정해놓은 artist_id가 맞아야만, result['tracks']에 저장하는 구조입니다. 간단하고 빠르게 해결할 수 있었지만 몇몇 아쉬운 점들이 있긴합니다.
배운 점
일단 이렇게 해결한 이유는
- 곧 올릴 BULK 데이터에 4만명의 아티스트 정보가 이미 포함되어 있음.
- 곡 제목에 피처링은 항상 명시 되며, RDB에서 피처링 아티스트를 넣기에는 데이터를 다시 추출해야하는 상황.
만약 시간이 충분했다면, 피처링 아티스트의 관계도 다시 한번 생각해봤을 것 같습니다. 그런데 이렇게 하다보니까, 정형적이지 않은 데이터의 특성을 가지고 있다면 NOSQL을 쓰는 것도 좋은 선택지가 됐을 것 같습니다. 저의 이번 실수로 깨달은 것들은..
- TEST 환경을 최대한 기존 환경과 동일하게 진행할 것(계속 간과하게 되는 것 같습니다)
- RDB에서 테이블 간의 관계를 잘 생각하고, 데이터를 적재할 것
- 지금은 운이 좋아서 TASK의 순서가 잘 맞았지만, 무결성 제약 조건에 따르면 artist 테이블보다, track 테이블을 먼저 업데이트하면 안되는 상황이였습니다.
- 테스트 할 때 생기는 의문점들을 반드시 해소하고 넘어갈 것
- 사실 TRACK 데이터를 뽑아내는 과정에서, TRACK 데이터에 있는 ARTIST_ID의 개수를 카운팅해봤었습니다. 당시에 ARTIST 데이터에 있는 ARTIST_ID와 불일치했음에도, 다른 부분이 잘못됐겠지하면서 넘어갔는데, 이게 결국엔 큰 일을 만드는 걸 또 다시 느낍니다..
실수를 했지만, 되게 많은 것들을 배울 수 있었습니다. 고민하는 과정을 더하는건 언제나 배울 점들이 많아지는 것 같습니다. DATA를 스케줄링할 때, 반드시 사전 점검하고 기본적인 무결성은 체크하고 넘어가야할 것 같습니다. 네 이번 포스팅은 여기까지고, 다음 포스팅에는 스케줄되는 데이터가 아니라, 저희가 지속적으로 수집하고 모아놓은 BULK 데이터를 한번에 올리는 포스팅을 진행하겠습니다. 감사합니다:)
'프로젝트 회고록 > 음악 평론 웹 제작 프로젝트' 카테고리의 다른 글
3. S3 데이터 가공해서 MYSQL로 적재하기 (2) | 2023.05.14 |
---|---|
2. SPOTIFY 데이터 AIRFLOW로 S3에 업로드하기 (0) | 2023.05.14 |
1. SPOTIFY API로 데이터 추출하기 (2) | 2023.05.14 |