您好,亲爱的stackoverflow社区
这是我的问题:
A)我在csv中有一些布尔列的数据;
不幸的是,这些列中的值为t
或f
(单字母);
这是我无法控制的工件(来自Redshift)。
B)我需要根据这些数据创建一个spark数据框,
希望转换t -> true
和f -> false
。
为此,我创建了一个Hive数据库和一个临时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 ...
,这会将我所有的t
和f
转换为Null。
所以:
D)我发现LazySimpleSerDe
大概必须按照我的意思进行(将t
和f
立即转换为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。
(:___
我为自己的CREATE TABLE尝试了几个小时的不同变体...
等
所有人都给我
df.head(5)
中没有)或我要说的真正问题是,没有一个单独的带有LazySimpleSerDe
的CREATE TABLE示例。
可以完成文档中所述的工作。
我真的非常感谢您的帮助或任何想法。我几乎拔了全部头发。
提前谢谢!
答案 0 :(得分:0)
SET hive.lazysimple.extended_boolean_literal=true;
例如,如果您有一个制表符分隔的文本文件,其中包含标题行,而't'/'f'表示true false:
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