Skip to content

Commit

Permalink
add some comments and test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
calvin committed May 27, 2016
1 parent 23eac38 commit c3d64fe
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 68 deletions.
7 changes: 5 additions & 2 deletions hive/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
__author__ = 'Hua Jiang'
__versioninfo__ = (1, 0, 0)
__version__ = '.'.join(map(str, __versioninfo__))
__title__ = 'hive-executor-py'

__all__ = [
]
from .executor import HiveExecutor, CommandResult
from .exceptions import HiveCommandExecuteError
from .exceptions import HiveUnfoundError
from .exceptions import SystemCommandExecuteError
97 changes: 60 additions & 37 deletions hive/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
# Author: Hua Jiang
# Date: 2016-04-23
# Desc:
#
# This module includes two classes below.
# An instance of the `CommandResult` class
# may be looked as a DTO(Data Transfer Object).Some of methods in the `HiveExecutor`
# class return result that is an instance of the `CommandResult` class.
# You can use straight the object of `HiveExecutor` class to operate hive.
######################################

import os
Expand All @@ -11,14 +15,11 @@
import logging
from collections import OrderedDict
from hive.exceptions import (HiveUnfoundError,
SystemCommandExecuteError,
HiveCommandExecuteError,
)
HiveCommandExecuteError)

_logger = logging.getLogger(__name__)



class CommandResult(object):
"""The class will be used to stored result of some methods in HivExecutor.
Expand Down Expand Up @@ -46,7 +47,7 @@ class HiveExecutor(object):
"""HiveExecutor may be looked as a wrapper of HiveCLI.
You can create an object of HiveExecutor,then execute most of Hive commands
by the class methods.When you instantiate the class,firstly check if hive
by the class methods.When you instantiate the class,firstly check if hive
client is available.So you can use it as a substitute for Hive Client.
Attributes
Expand All @@ -73,16 +74,16 @@ class HiveExecutor(object):
Examples
--------
>>> import HiveExecutor
>>> hive=HiveExecutor("hive")
>>> databases=hive.show_databases()
>>> from hive import HiveExecutor
>>> client=HiveExecutor("hive")
>>> databases=client.show_databases()
>>> print(databases)
['default', 'test']
>>> databases=hive.show_databases('defau*')
>>> databases=client.show_databases('defau*')
>>> print(databases)
['default']
>>> tables=hive.show_tables('default')
>>> tables=client.show_tables('default')
['table1', 'table2']
"""
Expand Down Expand Up @@ -127,8 +128,8 @@ def has_table(self, db_name, table_name):
return False

def show_tables(self, db_name, like_parttern=None):

if like_parttern:
"substitute for `show tables`"
if like_parttern:
like_parttern = "like '%s'" % (like_parttern)
else:
like_parttern = ""
Expand All @@ -145,8 +146,8 @@ def show_tables(self, db_name, like_parttern=None):
raise HiveCommandExecuteError(
"the hive command:%s error! error info:%s" % (hive_sql, cr.stderr_text))


def show_partitions(self, db_name, table_name, search_partitions=None):
"substitute for `show partitions`"
explicit_partition = ""
if search_partitions:
if isinstance(search_partitions, OrderedDict):
Expand All @@ -161,7 +162,8 @@ def show_partitions(self, db_name, table_name, search_partitions=None):
raise ValueError(
"The passed argument partition must be OrderedDict type.")

hive_sql = "use %s;show partitions %s %s;" % (db_name, table_name, explicit_partition)
hive_sql = "use %s;show partitions %s %s;" % (
db_name, table_name, explicit_partition)

_logger.debug("the function show_partitions() execute:%s" % (hive_sql))

Expand All @@ -176,8 +178,8 @@ def show_partitions(self, db_name, table_name, search_partitions=None):

return None


def show_functions(self):
"substitute for `show functions`"
hive_sql = "show functions;"

_logger.debug("executed hive sql:%s" % (hive_sql))
Expand All @@ -199,6 +201,7 @@ def has_function(self, function_name):
return False

def show_create_table(self, db_name, table_name):
"substitute for `show create table`"
hive_sql = "show create table %s.%s;" % (db_name, table_name)

_logger.debug("executed hive sql:%s" % (hive_sql))
Expand All @@ -212,6 +215,7 @@ def show_create_table(self, db_name, table_name):
"the hive command:%s error! error info:%s" % (hive_sql, cr.stderr_text))

def desc_table(self, db_name, table_name, extended=False):
"substitute for `desc table_name`"
hive_sql = "desc %s.%s;" % (db_name, table_name)

_logger.debug("executed hive sql:%s" % (hive_sql))
Expand Down Expand Up @@ -241,17 +245,16 @@ def _parse_table(self, text):
continue

line = line.strip()
if len(line)==0:
if len(line) == 0:
continue

field_info = {}
elements=None
m=re.match('(\S+)\s+(\S+)\s+(.*)',line)
elements = None
m = re.match('(\S+)\s+(\S+)\s+(.*)', line)
if m is None:
m=re.match('(\S+)\s+(\S+)',line)
m = re.match('(\S+)\s+(\S+)', line)

if m:
elements=m.groups()
elements = m.groups()

if elements:
if partition_info_flag:
Expand All @@ -260,13 +263,14 @@ def _parse_table(self, text):
fields_part_info.append(elements)
return table_info

def show_databases(self,like_parttern=None):
def show_databases(self, like_parttern=None):
"substitute for `show databases`"
if like_parttern:
like_parttern = "like '%s'" % (like_parttern)
else:
like_parttern = ""

hive_sql="show databases %s;" %(like_parttern)
hive_sql = "show databases %s;" % (like_parttern)

_logger.debug("executed hive sql:%s" % (hive_sql))
cr = self.execute(sql=hive_sql)
Expand All @@ -278,9 +282,10 @@ def show_databases(self,like_parttern=None):
raise HiveCommandExecuteError(
"the hive command:%s error! error info:%s" % (hive_sql, cr.stderr_text))


def desc_database(self, db_name, extended=False):
hive_sql = "set hive.cli.print.header=true;desc database %s;" % (db_name)
"substitute for `desc database`"
hive_sql = "set hive.cli.print.header=true;desc database %s;" % (
db_name)

_logger.debug("executed hive sql:%s" % (hive_sql))
cr = self.execute(sql=hive_sql)
Expand All @@ -292,18 +297,20 @@ def desc_database(self, db_name, extended=False):
raise HiveCommandExecuteError(
"the hive command:%s error! error info:%s" % (hive_sql, cr.stderr_text))


def _parse_database(self,text):
def _parse_database(self, text):
"unsupported"
return text


def desc_function(self, db_name, table_name, extended=False):
"unsupported"
pass

def desc_formatted_table(self,db_name,table_name):
def desc_formatted_table(self, db_name, table_name):
"unsupported"
pass

def show_roles(self):
"substitute for `show roles`"
hive_sql = "show roles;"

_logger.debug("executed hive sql:%s" % (hive_sql))
Expand All @@ -317,9 +324,11 @@ def show_roles(self):
"the hive command:%s error! error info:%s" % (hive_sql, cr.stderr_text))

def drop_table(self, db_name, table_name):
"unsupported"
pass

def create_table(self, create_table_sql):
"unsupported"
pass

def _parse_partitions(self, text):
Expand Down Expand Up @@ -356,14 +365,28 @@ def _execute_system_command(self, command):
return CommandResult(output, err, status)

def execute(self, variable_substitution=None, init_sql_file=None, sql_file=None, sql=None, output_file=None):
"""this method can be used to execute hive cliet commands.
Parameters
----------
variable_substitution : Optional[str]
The parameter that contains key-value pairs is a dict type variant.
init_sql_file : Optional[str]
The path of the initialization sql file
sql_file : Optional[str]
The path of the hive sql
sql : Optional[str]
The hive sql,if this parameter is required,the parameter of the sql_file will be disable.
output_file : Optional[str]
When passed the parameter 'sql',this parameter can be used.
Raises
------
ValueError
The parameters violate the rules below.
"""
Parameters:
variable_substitution:The parameter that contains key-value pairs is a dict type variant.
init_sql_file:the path of the initialization sql file
sql_file:the path of the hive sql
sql:the hive sql,if this parameter is required,the parameter of the sql_file will be disable.
output_file:when passed the parameter 'sql',this parameter can be used.
"""

# validate the parameters
if variable_substitution and not isinstance(variable_substitution, dict):
raise ValueError(
Expand Down
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[bdist_wheel]

universal=1
57 changes: 28 additions & 29 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,31 @@
https://packaging.python.org/en/latest/distributing.html
https://github.com/pypa/sampleproject
"""
#!/usr/bin/env python

# Always prefer setuptools over distutils
from setuptools import setup, find_packages
from setuptools import setup
# To use a consistent encoding
from codecs import open
from os import path

here = path.abspath(path.dirname(__file__))
#here = path.abspath(path.dirname(__file__))

# Get the long description from the README file
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
long_description = f.read()
# with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
# long_description = f.read()

setup(
name='hive',
name='hive-executor-py',

# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/single_source_version.html
version='1.0.0',
version='1.0.1.dev1',

description='A hive client python project',
long_description=long_description,
#long_description=long_description,

# The project's main homepage.
url='https://github.com/pypa/sampleproject',
url='https://github.com/calvinjiang/hive-executor-py',

# Author details
author='Calvin Jiang',
Expand All @@ -43,7 +42,7 @@
# 3 - Alpha
# 4 - Beta
# 5 - Production/Stable
'Development Status :: 3 - Alpha',
'Development Status :: 4 - Beta',

# Indicate who your project is intended for
'Intended Audience :: Developers',
Expand All @@ -54,7 +53,7 @@

# Specify the Python versions you support here. In particular, ensure
# that you indicate whether you support Python 2, Python 3 or both.
'Programming Language :: Python :: 2',
#'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
Expand All @@ -64,11 +63,11 @@
],

# What does your project relate to?
keywords='sample setuptools development',
keywords='hive client python',

# You can just specify the packages manually here if your project is
# simple. Or you can use find_packages().
packages=find_packages(exclude=['contrib', 'docs', 'tests']),
packages=['hive'],

# Alternatively, if you want to distribute just a my_module.py, uncomment
# this:
Expand All @@ -78,36 +77,36 @@
# your project is installed. For an analysis of "install_requires" vs pip's
# requirements files see:
# https://packaging.python.org/en/latest/requirements.html
install_requires=['peppercorn'],
#install_requires=['peppercorn'],

# List additional groups of dependencies here (e.g. development
# dependencies). You can install these using the following syntax,
# for example:
# $ pip install -e .[dev,test]
extras_require={
'dev': ['check-manifest'],
'test': ['coverage'],
},
#extras_require={
# 'dev': ['check-manifest'],
# 'test': ['coverage'],
#},

# If there are data files included in your packages that need to be
# installed, specify them here. If using Python 2.6 or less, then these
# have to be included in MANIFEST.in as well.
package_data={
'sample': ['package_data.dat'],
},
#package_data={
# 'sample': ['package_data.dat'],
#},

# Although 'package_data' is the preferred approach, in some case you may
# need to place data files outside of your packages. See:
# http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa
# In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
data_files=[('my_data', ['data/data_file'])],
#data_files=[('my_data', ['data/data_file'])],

# To provide executable scripts, use entry points in preference to the
# "scripts" keyword. Entry points provide cross-platform support and allow
# pip to create the appropriate form of executable for the target platform.
entry_points={
'console_scripts': [
'sample=sample:main',
],
},
)
#entry_points={
# 'console_scripts': [
# 'sample=sample:main',
# ],
#},
)
4 changes: 4 additions & 0 deletions tests/test_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ def test_show_tables(self):
self.assertRaises(HiveCommandExecuteError,
self.executor.show_tables, "test_db_name")

def test_show_databases(self):
if self.hive_enable:
self.assertEqual([],HiveCommandExecuteError,self.executor.show_databases("notexists_db_name"))

def tearDown(self):
self.executor = None

Expand Down

0 comments on commit c3d64fe

Please sign in to comment.