data engineering

python으로 hive의 쿼리 자동화하기.

qkqhxla1 2019. 3. 13. 16:46

이전에 지금 쓸 글과 비슷한 https://qkqhxla1.tistory.com/958 를 썼었다.

현재 회사에서는 단순 조회용으로 presto를 쓰고,(조회용으로는 presto가 더 빠르고 좋다는 설명을 들었다.) create alter 같은 ddl은 hive에서 쿼리를 돌린다. 


1. impyla 모듈사용.(추천하는 방법..)

다시 보는데 impyla를 사용하는게 가장 안정적이고 좋다. 이거를 쓰자. 아래는 예제 코드.

# pip install thrift==0.9.3  # 안정적인 thrift버전임.
from impala.dbapi import connect
from impala.error import ProgrammingError

~~~~~
def get_hive_results(self, hql):
        print 'hql =',hql
        with connect(
                host='<namenode address=>',
                port=<port>,
                auth_mechanism='PLAIN') as conn:
            if isinstance(hql, basestring):
                hql = [hql]
            results = {'data': [], 'header': [] }
            cur = conn.cursor()
            for statement in hql:
                cur.execute(statement)
                records = []
                try:
                    records = cur.fetchall()
                except ProgrammingError:
                    print('no record returned')
                if records:
                    results = {'data': records, 'header': cur.description}
            return results['data']


2. pyhive모듈 사용하기.. (비추천... 쓰다보니 서버 셋팅에 따라 동작 안할수도 있다. 설치는 간단한데 안될수도 있어서 비추천.)

https://github.com/dropbox/PyHive pyhive에서 connect시에 namenode주소를 입력한다.

ex) internal-price-emr-common-123123123.ap-northeast-2.elb.amazonaws.com (aws에 있는 namenode의 경우.)

이게 제일 간단하다. 

나는 우분투에 설치했을때 https://github.com/dropbox/PyHive/issues/161 이 에러가 났었는데 libsasl2-modules거 설치하니까 해결되었다.

아래는 jdbc를 사용해서도 삽질을 해봐서 정리해둠. 근데 어차피 쿼리 돌아가는건 똑같고.. 아래는 추가적으로 jar가 필요하기에 굳이 pyhive가 된다면 사용할 이유가 없을것같다.

3. jdbc jar을 이용한 방법.


지금까지 select만 필요해서 다른 방법은 안 알아보고있었는데 alter도 자동화해야할때가 와서 찾아봤다. 이전에 쓴 글에 요 링크를 걸어놨었는데 서로 버전이 틀려서인지 자바 세팅이 조금 달라서 그런지 잘 되지 않았다. 

'Class org.apache.hive.jdbc.HiveDriver not found'가 자꾸 뜨는데 난 분명히 맞는 jar인 'hive-jdbc-3.1.1.jar'를 세팅해줬었다. 

왜안되지하고 찾아보니 동일한 문제를 겪는 사람을 많이 봤다... 그런데 https://github.com/baztian/jaydebeapi/issues/34에서 방법을 찾았는데 인자를 줄때 명시적으로 주면 된다...


근데 그렇게 명시적으로 선언해주고 돌리니까 또다른 class not found에러가 뜸.(java.lang.NoClassDefFoundError: org/apache/hive/service/rpc/thrift/TCLIService$Iface)

... https://community.hortonworks.com/articles/149869/custom-java-applications-throw-classnotfoundexcept.html

요걸 보니 hive-jdbc-3.1.1.jar 말고 hive-jdbc-3.1.0.3.1.2.0-4-standalone.jar 처럼 standalone가 붙은 jar로 하라고 함.


찾다가 https://repo.spring.io/simple/hortonworks/org/apache/hive/hive-jdbc/ 여기서 jar리스트를 발견해서 최신 버전을 다운받았다.


삽질하면서 본건데 또 jar파일 버전하고 하이브서버의 버전이 맞지 않으면 또다른 에러가 터질수도 있다고한다.


드럽게 복잡하다. 예시는 select로 했는데 다른것도 된다.

import jaydebeapi

#Connect to HiveServer2
conn = jaydebeapi.connect(jclassname="org.apache.hive.jdbc.HiveDriver",
                          url='jdbc:hive2://하이브서버 주소:포트/기본 스키마;',
                          jars='/Users/qkqhxla1/Downloads/hive-jdbc-3.1.0.3.1.2.0-4-standalone.jar',)
cursor = conn.cursor()

# Execute SQL query
# sql = "alter table test.qkqhxla1_test add columns (python_test string)"
sql = 'select * from test.qkqhxla1_test'
cursor.execute(sql)
results = cursor.fetchall()
for r in results:
    for rr in r:
        print rr,
    print