현재 리뷰 프로젝트를 진행하면서 리뷰 파일을 csv로 만들고 데이터베이스에 업로드 시키고 pandas의 read_csv로 읽게 했다. 물론 모든 곳에 encoding='utf-8'
cp949 인코딩도 안 되는 것인가?
이 문제는 리뷰에 섞여있는 이모티콘(emoji) 때문에 발생했다고 추측 중이다.
일부 리뷰에는 문제 없이 잘 작동하는 걸로 보아 cp949 인코딩이 해석할 수 없는 문자(이모티콘)가 들어가서 이런 문제가 발생한 듯 하다.
UnicodeEncodeError: 'cp949' codec can't encode character '\U0001f44d' in position 431: illegal multibyte sequence
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
if encoding is not specified the encoding used is platform dependent:
파이썬 공식 문서의 open() 함수 설명 일부이다.
encoding의 default는 none이어서 따로 지정을 안 해주면 플랫폼 기본 설정(나의 경우 윈도우라 cp949 인코딩)으로 열고 있었다.
아.....
문제 발생점으로 여겨지는 django.core.files.File 의 open() 함수
def open(self, mode=None):
if not self.closed:
self.seek(0)
elif self.name and os.path.exists(self.name):
self.file = open(self.name, mode or self.mode)
else:
raise ValueError("The file cannot be reopened.")
return self
이 부분에서 open() 함수에 encoding='utf-8'을 추가해봤다.
??? 그래도 안 된다.
이모티콘은 단순 인코딩 종류 문제가 아니라 byte 문제인 거 같다.
알아보니 emoji는 4바이트를 사용한다. 일반 utf-8은 2바이트이다.
단순히 csv 파일을 작성할 때 이모티콘이 있어도 문제가 없다. (encoding='utf-8' 기준)
확인해 보니 한글도 안 깨지고 이모티콘도 잘 담겨있다.
그러나 django.core.files 의 File()을 사용해서 코드 상에서 직접 파일을 저장하면 문제가 생긴다.
한글이 깨지고 이모티콘이 살았는 지도 알 수 없다.
보통 utf-8은 1바이트에서 4바이트까지 커버할 수 있다.
데이터베이스 종류에 따라 utf-8이 3바이트만 저장 가능할 수도 있다.(Mysql은 3바이트 제한)
django에서는 업로드한 파일이 아닌 코드 상에서 추가된 파일은 조금씩 쪼개서 읽은 뒤 저장한다. 그렇기 때문에 문제가 발생했을 수 있다.
더 이상 이 문제로 골치 아프고 싶지 않았다. 그래서 Model을 살짝 바꿔서 FileField 대신 FilePathField를 사용했다.
처음 생성되는 csv 파일에는 한글도 이모티콘도 잘 담겨 있었기 때문에 이 선택을 할 수 있었다.
python의 open 함수로 csv 파일을 만들고 직접 경로에 추가해준 뒤 해당 경로를 데이터베이스에 저장하는 방식이다.
이모티콘이 섞여있는 리뷰에서 테스트 결과 아무 문제 없이 Reivew 데이터까지 잘 생성했다.
인코딩 문제로 고생 중이라면 어쩌면 데이터베이스의 문제일 수 있다고 말해주고 싶다.
'프로젝트 > 리뷰집' 카테고리의 다른 글
꼬꼬마(kkma)의 메모리 효율 문제 - konlpy 품사 태거에 대해 (0) | 2021.02.14 |
---|---|
rmsprop vs adam 나에게는 어떤 optimizer가 더 좋을까? (0) | 2021.02.13 |
konlpy 형태소 분석(품사 태깅) 결과 비교 (0) | 2021.02.12 |
tensorflow 사용하는 프로젝트 heroku에 배포 - tensorflow-cpu를 사용하자 (0) | 2021.02.10 |
error 발생: jpype 버전 주의하세요 (0) | 2021.02.10 |