簡體   English   中英

PySpark/Hive:如何使用 LazySimpleSerDe 創建表以轉換布爾值“t”/“f”?

[英]PySpark/Hive: how to CREATE TABLE with LazySimpleSerDe to convert boolean 't' / 'f'?

親愛的 stackoverflow 社區,您好,

這是我的問題:


A)我在csv中有一些布爾列的數據; 不幸的是,這些列中的值是tf (單個字母); 這是我無法控制的工件(來自 Redshift)。

B)我需要從這些數據創建一個火花數據框,希望轉換t -> truef -> 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 ...

,這會將我所有的tf轉換為空值。

所以:

D)我發現LazySimpleSerDe大概必須按照我的意思做(將tf即時轉換為truefalse )。 來自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 嘗試了幾個小時的不同變體......

  • 有或沒有SERDEPROPERTIES,
  • 有或沒有 TBLPROPERTIES,
  • 帶有“由...終止的字段”或不帶,

等等。

都給我

  • Null 代替 't' 和 'f',或
  • 一個空的 df ( df.head(5)沒有任何內容),或
  • 語法錯誤,或
  • 大約 100 頁的 Java 異常。

我會說,真正的問題是,沒有一個使用LazySimpleSerDe的 CREATE TABLE 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM