Drop Table语句中的Hive ParseException

时间:2017-05-06 13:37:20

标签: python hadoop encoding hive pyodbc

我特别使用python和pyodbc模块在Hadoop上执行Hive查询。代码触发问题的部分如下:

import pyodbc
import pandas

oConnexionString = 'Driver={ClouderaHive};[...]'
oConnexion = pyodbc.connect(oConnexionString, autocommit=True)
oConnexion.setencoding(encoding='utf-8')
oQueryParameter = "select * from my_db.my_table;"
oParameterData = pandas.read_sql(oQueryParameter, oConnexion)
oCursor = oConnexion.cursor()

for oRow in oParameterData.index:
    sTableName = oParameterData.loc[oRow,'TableName']
    oQueryDeleteTable = 'drop table if exists my_db.' + sTableName + ';'
    print(oQueryDeleteTable)
    oCursor.execute(oQueryDeleteTable)

该印刷品给出了这个:drop table if exists dl_audit_data_quality.hero_context_start_gamemode;

但是cursor.execute会触发以下错误消息

  

pyodbc.Error:('HY000',“[HY000] [Cloudera] [HiveODBC](80)语法或   execurint查询时在服务器中抛出的语义分析错误。错误   来自服务器的消息:编译语句时出错:FAILED:   ParseException行1:44字符'(80)(SQLExecDirectW)“)

请注意,当我复制打印并在Hue中手动执行时,它运行良好。我猜这与变量sTableName的编码有关,但我无法弄清楚如何修复它。

由于

1 个答案:

答案 0 :(得分:1)

由于变量sTableName的编码不正确,查询失败。 单独打印变量将正确显示文本。以上打印示例:

>>> print(oQueryDeleteTable)
>>> 'drop table if exists dl_audit_data_quality.hero_context_start_gamemode;'

但是打印原始数据框显示它包含如下字符:

>>> print(oParameterData.loc[oRow,'TableName']
>>> 'h\x00e\x00r\x00o\x00_c\x00o\x00n\x00t\x00e\x00x\x00t\x00'

问题通过重新编写如下所述的编码来解决:Python Dictionary Contains Encoded Values

import pyodbc
import pandas

oConnexionString = 'Driver={ClouderaHive};[...]'
oConnexion = pyodbc.connect(oConnexionString, autocommit=True)
oConnexion.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8')
oConnexion.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8')
oConnexion.setencoding(encoding='utf-8')
oQueryParameter = "select * from my_db.my_table;"
oParameterData = pandas.read_sql(oQueryParameter, oConnexion)
oCursor = oConnexion.cursor()

for oRow in oParameterData.index:
    sTableName = oParameterData.loc[oRow,'TableName']
    oQueryDeleteTable = 'drop table if exists my_db.' + sTableName + ';'
    print(oQueryDeleteTable)
    oCursor.execute(oQueryDeleteTable)