“转换”如何影响存储到磁盘并从磁盘值读取?

时间:2014-06-21 00:49:50

标签: python hive

我正在尝试理解Hive中空值的处理,特别是在Python变换中检查空值时。

我一直在阅读这个关于变换的维基页面:

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Transform

具体来说,我正在看第二段:

  

默认情况下,列将转换为STRING并由TAB分隔,然后输入用户脚本;类似地,所有NULL值都将转换为文字字符串\ N,以便将NULL值与空字符串区分开来。用户脚本的标准输出将被视为TAB分隔的STRING列,任何仅包含\ N的单元格将被重新解释为NULL,然后生成的STRING列将转换为表格声明中指定的数据类型以通常的方式。用户脚本可以将调试信息输出到标准错误,该错误将显示在hadoop上的任务详细信息页面上。可以使用ROW FORMAT ....覆盖这些默认值。

但是当我说“所有NULL值”时,我想我很困惑,它如何确定该值是否为NULL?它是否足够聪明以考虑“serialization.null.format”表属性?

如果我正确理解文档,我认为默认行为是这样的:

要存储到磁盘的值=>实际存储到磁盘的值=>通过TRANSFORM发送给Python的值

注意\N不是转义序列,而是文字的双字符串反斜杠capital-n

  • (空字符串)=> (空字符串)=> “\N
  • (null value)=> (空字符串)=> “\N
  • 'NULL'=> 'NULL'=> 'NULL'
  • \N”=> “\N”=> “\N

对这种理解的任何更正都会很棒。 :)

我不是在处理默认情况。我正在开发一个系统,其中所有表都设置了此表属性:

TBLPROPERTIES ('serialization.null.format'='NULL')

我从文档中一点都不清楚这将如何影响这些值如何存储到磁盘以及如何在TRANSFORM期间将它们翻译并发送到Python:

要存储到磁盘的值=>实际存储到磁盘的值=>通过TRANSFORM发送给Python的值

同样,\N不是转义序列,而是文字的两个字符串反斜杠大写字母n。

  • (空字符串)=> (空字符串)=> ???
  • (null value)=> 'NULL'=> ???
  • 'NULL'=> 'NULL'=> ???
  • “\ N”=> “\ N”=> “\ N”

所以我的主要问题是,是否有人能够对第二种情况提供一些见解/清晰度?我需要知道这些值将如何显示在Python中,以便我可以正确检查该值是否为空。

1 个答案:

答案 0 :(得分:1)

我从文档中了解到,Hive Transform根本不使用“serialization.null.format”表属性。它有自己的空值替换:

value in table | given to python script
---------------------------------------
empty string   | empty string
null value     | \N
NULL           | NULL
\N             | \N

因此,您必须清理可能包含\N的列作为其值,因为您必须对可能包含选项卡的任何列执行此操作。引用页面上有明确的警告:

  

警告:您有责任在转换之前清理任何STRING列。如果您的STRING列包含选项卡,身份转换器将不会回复您的开始!为了解决这个问题,请参阅REGEXP_REPLACE并将选项卡替换为路径中的其他字符进入TRANSFORM()调用。

因此,对于所有非字符串列,一切都很好:它不能包含制表符和\N,并且Python脚本只需要考虑\N是空值的表示。

如果你有一个String,你确定它们既不包含标签也不包含\N,那也没关系,它与前一种情况相同,空字符串是......一个空字符串!

如果字符串列可以包含选项卡,但是有另一个字符不能出现(比如|),则在MAP子句选项卡中将|替换为regexp_replace,即python脚本必须知道此列中的|是一个选项卡,并且您在REDUCE子句中使用反向regexp_replace

如果字符串列可以包含\N,但是有另一个字符串不能存在,则可以应用前一个规则。

在更一般的情况下,我认为唯一的防弹解决方案是将空值转换为\N结束编码base64中的所有非空值(\N希望不是有效的base64值...)使用if (A IS NULL, '\N', base64(binary(A)))之类的内容并使用if (A = '\N', NULL, cast(unbase64(A) as STRING))

解码