PySpark/Hive:如何使用LazySimpleSerDe创建TABLE来转换布尔't'/'f'?



你好亲爱的堆栈溢出社区,

这是我的问题:


A( 我有一些布尔列的 csv 数据; 不幸的是,这些列中的值是tf(单个字母(; 这是我无法控制的神器(来自Redshift(。

B( 我需要从这些数据创建一个火花数据帧, 希望转换t -> truef -> false. 为此,我创建了一个 Hive DB 和一个临时 Hive 表 然后从中SELECT *,如下所示:

sql_str = """SELECT * FROM {db}.{s}_{t} """.format(
db=hive_db_name, s=schema, t=table)
df = sql_cxt.sql(sql_str)

这有效,我可以打印 df,它为我提供了具有正确数据类型的所有列。 但:

C( 如果我像这样创建表:

CREATE EXTERNAL TABLE IF NOT EXISTS {db}.{schema}_{table}({cols})                    
ROW FORMAT DELIMITED                                                                                          
FIELDS TERMINATED BY '|t'                                                                                     
STORED AS TEXTFILE 
LOCATION ...

,这会将我所有的tf转换为空值。

所以:

D(我发现了LazySimpleSerDe可能必须按照我的意思去做(将tf转换为true并即时false(。从https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties(引用(:

"""
hive.lazysimple.extended_boolean_literal
Default Value: false
Added in: Hive 0.14 with HIVE-3635
LazySimpleSerDe uses this property to determine 
if it treats 'T', 't', 'F', 'f', '1', and '0' as extended, 
legal boolean literals, in addition to 'TRUE' and 'FALSE'. 
The default is false, which means only 'TRUE' and 'FALSE' 
are treated as legal boolean literals.
"""

根据这一点(或者至少我认为是这样(,我现在在 Hive DB 中创建一个表,如下所示:

create_table_sql = """
CREATE EXTERNAL TABLE IF NOT EXISTS {db_name}.{schema}_{table}({cols})
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES ("separatorChar" = "|")
STORED AS TEXTFILE
LOCATION '{loc}'
TBLPROPERTIES ('hive.lazysimple.extended_boolean_literal'='true')
""".format(db_name=hive_db_name,
schema=schema,
table=table,
cols=",n".join(cols),
loc=location)
return sql_cxt.sql(create_table_sql)

这确实会创建一个表, 我可以再次看到所有具有正确数据类型的列,df.count()是正确的,但仍然df.head(3)给我布尔列的所有值 == Null。

(:___


我为我的创建表尝试了几个小时的不同变体......

  • 有或没有SERDEPROPERTIES,
  • 有或没有TBLPROPERTIES,
  • 使用"字段终止者..."或没有,

等。

都给我一个

  • 为空代替"t"和"f",或
  • 一个空的 df(df.head(5)中没有任何东西(,或者
  • 语法错误,或
  • 大约 100 页的 Java 异常。

真正的问题是,我想说,没有一个单一的例子 创建表 与LazySimpleSerDe这将完成文档中描述的工作。

我真的非常感谢您的帮助或任何想法。我几乎拔掉了所有的头发。

提前谢谢你!

根据 jira 问题中的补丁:

SET hive.lazysimple.extended_boolean_literal=true;

例如,如果您有一个制表符分隔的文本文件,其中包含标题行,并且"t"/"f"表示真假:

create table mytable(myfield boolean)
row format delimited
fields terminated by 't'
lines terminated by 'n'
location '/path'
tblproperties (
'skip.header.line.count' = '1'
);
...
select count(*) from mytable where myfield is null; <-- returns 100% null
...
SET hive.lazysimple.extended_boolean_literal=true;
select count(*) from mytable where myfield is null; <-- changes the serde to interpret the booleans with a more forgiving interpretation, yields a different count

最新更新