BigQuery JSON 문자열에서 원하는 값 추출하기

BigQuery 테이블에 어떤 필드에 JSON 문자열이 들어 있고 이 JSON 문자열에서 어떤 키에 해당하는 값을 가져오는 간단한 쿼리 스니펫입니다.

들어있는 JSON 문자열의 포맷이 큰 문제가 없으면 괜찮은데 아닌 경우가 있습니다. 그래서 간단하게 쿼리를 돌려서 테스트 해봤습니다.

BigQuery에 JSON 문자열에서 원하는 키에 해당하는 값을 가져오는 샘플 쿼리입니다.

간단한 테스트를 하는데 테이블을 만드는 것이 귀찮으니 JSON 문자열 여러 개를 array로 만들고 UNNEST로 꺼내서 합니다. 다른 데이터베이스에서는 UNION ALL을 하고 INLINE VIEW로 묶어서 꺼내거나 LATERAL VIEW를 쓰면 됩니다.

SELECT json_str                                AS json_str
     , JSON_EXTRACT_SCALAR(json_str, '$.prob') AS prob_scala
     , JSON_EXTRACT_SCALAR(json_str, '$.bin')  AS bin_scala
     , JSON_EXTRACT(json_str, '$.prob')        AS prob_str
     , JSON_EXTRACT(json_str, '$.bin')         AS bin_str
FROM UNNEST([
                '{}',
                '{"prob":"0.413656","bin":"0"}',
                '{"prob":"0.010643","bin":"3"}',
                '{"prob":"0.000114","bin":"2"}',
                '{"prob":"0.802312","bin":"NULL"}',
                '{"prob":"NULL","bin":"NULL"}',
                '{"prob":"NULL","bin":"65"}',
                '{prob:"0.627363",bin:23}',
                '{\'prob\':0.27372,\'bin\':45}'
    ]) AS json_str
;

결과를 TSV형태로 뽑아보면 다음과 같습니다.

json_str	prob_scala	bin_scala	prob_str	bin_str
{}
{"prob":"0.413656","bin":"0"}	0.413656	0	"0.413656"	"0"
{"prob":"0.010643","bin":"3"}	0.010643	3	"0.010643"	"3"
{"prob":"0.000114","bin":"2"}	0.000114	2	"0.000114"	"2"
{"prob":"0.802312","bin":"NULL"}	0.802312	NULL	"0.802312"	"NULL"
{"prob":"NULL","bin":"NULL"}	NULL	NULL	"NULL"	"NULL"
{"prob":"NULL","bin":"65"}	NULL	65	"NULL"	"65"
{prob:"0.627363",bin:23}
{'prob':0.27372,'bin':45}	0.27372	45	0.27372	45

저렇게 보면 눈에 잘 안 들어오는데 이렇게 보면 실제 NULL값과 “NULL”이라는 문자열 그리고 key가 따옴표 또는 큰타옴표로 묶여 있지 않는 것들이 어떻게 처리되는지 볼 수 있습니다.

위의 결과는 DataGrip에서 결과를 확인한 것입니다.
결과를 자세히 보시면 알겠지만 사용할 때 주의할 점은 이렇습니다.

  • 우선 JSON의 안쪽에 키(key)는 큰따옴표 또는 작은따옴표로 묶여 있어야 합니다.
  • JSON_EXTRACT는 키에 해당하는 값을 통째로 다 문자열로 가져옵니다
  • JSON_EXTRACT_SCALA는 키에 해당하는 값에서 큰따옴표, 작은따옴표를 없애고 알맹이만 꺼내 옵니다.

Docker proxy 설정

Docker를 사용할 때 docker를 구동시킬 서버가 방화벽 안쪽에 있거나 외부 네트워크(인터넷)에 직접 접속하지 못해서 docker image를 당겨오거나 docker container를 빌드하지 못할 때가 있습니다.

Proxy를 사용해야 하는데 다음과 같이 하면 됩니다.

구동할 서버의 구동할 계정에 디렉토리를 하나 생성하고 파일을 만듭니다.

mkdir ~/.docker
vim ~/.docker/config.json

아래의 내용을 추가해줍니다. proxy 서버의 주소와 port는 각자의 네트워크에 해당하는 것으로 바꾸면 됩니다.

{
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://proxy.test.com:8080",
     "httpsProxy": "http://proxy.test.com:8080",
     "noProxy": "localhost,127.0.0.1"
   }
 }
}

그리고 나서 다시 docker로 container를 빌드하면 됩니다.

Fatal Python error: _PySys_BeginInit: can't initialize sys module

Linux에서 Python을 소스코드로 빌드해서 설치하려고 할 때 위와 같은 메시지가 보이면서 빌드가 안될때가 있습니다.

원인은 랭귀지 설정이나 환경설정이 빌드에 맞지 않기 때문에 발생하는 것인데 일일히 원인을 찾아서 해결하기가 매우 번거롭습니다. 로케일 설정(locale)같은 것이나 몇개를 수정하면 된다는 글을 찾아 볼 수 있지만 생각만큼 잘 되지 않고 많은 시간을 허비해야 합니다.

가장 간단한 해결책은 root로 로그인 또는 su로 root 전환을 해서 빌드하면 됩니다. 빌드할 때 sudo를 사용해도 잘 되지 않으므로 확실하게 root로 로그인해서 빌드하면 됩니다.

Python 소스 컴파일에서 Error in `python': corrupted size vs. prev_size 에러

리눅스에 문제가 있거나 너무 오래된 버전의 리눅스 배포판을 사용할 때 Python source를 다운로드 받아서 빌드해야 하는 경우가 있습니다

이때 configure를 실행한 뒤 make 를 실행하면 다음과 같은 에러가 나올 수 있습니다.

Error in `python': corrupted size vs. prev_size

해결책은 다음과 같이 하면 됩니다.

sudo apt-get install libtcmalloc-minimal4
export LD_PRELOAD="/usr/lib/libtcmalloc_minimal.so.4"

Ubuntu 14.04에 Python 3.7 설치하기

오래된 Ubuntu 14.04에 Python 3.7을 설치할 때 필요한 간단한 절차입니다. 이 글을 쓰는 시점에서의 최신 Ubuntu 18.04이고 곧 20.04 버전이 나올 예정입니다.

그리고 현재 Python은 3.7.x가 최신 버전인데 Ubuntu 14.04에는 3.6.x가 설치되어 있고 14.04에 3.7.x는 그냥은 설치되지 않습니다.

3.6.x를 그냥 쓰면 되지 않겠냐고 하겠지만 3.6과 3.7은 마이너 버전 하나의 차이로 보이지만 실제로는 많은 부분에서 차이가 있습니다. 성능, 보안, 문법과 같은 것들입니다. 최신 패키지들도 3.6에서는 오작동하는 사례가 많습니다.
3.7을 설치해서 사용하는 것이 좋습니다.

sudo apt update  # 깨끗하게 한번 apt 정보 갱신
sudo apt install software-properties-common  # add-apt-repository 명령어를 설치하기 위한 것
sudo add-apt-repository ppa:deadsnakes/ppa  # 레파지토리를 등록합니다.
sudo apt update  # apt에 정보를 업데이트합니다.
sudo apt install python3.7  # python 3.7을 설치합니다.