Hive外部表跳过第一行

我正在使用Cloudera的Hive版本,并尝试通过包含第一列中列名的csv文件创build外部表。 这里是我用来做到这一点的代码。

CREATE EXTERNAL TABLE Test ( RecordId int, FirstName string, LastName string ) ROW FORMAT serde 'com.bizo.hive.serde.csv.CSVSerde' WITH SerDeProperties ( "separatorChar" = "," ) STORED AS TEXTFILE LOCATION '/user/File.csv' 

样本数据

 RecordId,FirstName,LastName 1,"John","Doe" 2,"Jane","Doe" 

任何人都可以帮助我如何跳过第一行,或者我需要添加一个中间步骤?

数据中的标题行在Hive中是永久的头痛。 在修改Hive源代码的时候,我相信如果没有一个中间步骤,就不能走开。 (编辑:这不再是真实的,见下面的更新)

不幸的是,你回答的问题。 我会提出一些完整性的中间步骤的想法。

如果您愿意在触及表的每个查询上筛选出标题行,则可以在数据加载中不需要额外的步骤。 不幸的是,这在其他地方增加了一个额外的设置。 当标题行违反了你的模式时,你将不得不变得聪明/杂乱。 如果你采用这种方法,你可以考虑编写一个自定义的SerDe,使得这一行更容易过滤。 不幸的是,SerDe不能完全删除行(或者可能形成一个可能的解决scheme),他们必须返回类似null东西。 我从来没有见过这种方法在实践中采取处理标题行,因为它使阅读痛苦,阅读往往比写作更为普遍。 如果您正在处理一个表,或者如果标题行只是许多格式不正确的行中的一行,那么它可能有一席之地。

您可以通过删除数据加载中的第一行来进行一次过滤。 INSERT语句中的WHERE子句可以做到这一点。 你可以使用像sed这样的工具来摆脱它。 我已经看到两种方法。 在你采取哪种方法之间进行权衡,也不是处理标题行的真正方法。 不幸的是,这两种方法都需要时间,需要临时重复数据。 如果您绝对需要另一个应用程序的标题行,则重复将是永久性的。

更新:

从Hive v0.13.0开始,你可以使用skip.header.line.count。 创build表格时也可以指定相同的值。 例如:

 create external table testtable (name string, message string) row format delimited fields terminated by '\t' lines terminated by '\n' location '/testtable' tblproperties ("skip.header.line.count"="1"); 

虽然你有Daniel的答案,但是可以使用OpenCSVSerde进行一些定制:

 CREATE EXTERNAL TABLE `mydb`.`mytable`( `product_name` string, `brand_id` string, `brand` string, `color` string, `description` string, `sale_price` string) PARTITIONED BY ( `seller_id` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH SERDEPROPERTIES ( 'separatorChar' = '\t', 'quoteChar' = '"', 'escapeChar' = '\\') STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION 'hdfs://namenode.com:port/data/mydb/mytable' TBLPROPERTIES ( 'serialization.null.format' = '', 'skip.header.line.count' = '1') 

借此,您可以完全控制分隔符,引号字符,转义字符,空处理和标题处理。

看这里和这里 。

我不太确定它是否与ROW FORMAT serde'com.bizo.hive.serde.csv.CSVSerde'一起工作,但我想它应该类似于ROW FORMAT DELIMITED FIELDS TERMINATED BY','。
在你的情况下,第一行将被视为正常的行。 但是第一个字段不能是INT,因此第一行的所有字段都将被设置为NULL。 你只需要一个中间步骤来解决它:

 INSERT OVERWRITE TABLE Test SELECT * from Test WHERE RecordId IS NOT NULL 

只有一个缺点是你的原始csv文件将被修改。 我希望它有帮助。 GL!

我也为此苦苦挣扎,没有办法告诉蜂房跳过第一排,就像Greenplum那样。 所以最后我不得不从文件中删除它。 例如“cat File.csv | grep -v RecordId> File_no_header.csv”

 create external table table_name( Year int, Month int, column_name data_type ) row format delimited fields terminated by ',' location '/user/user_name/example_data' TBLPROPERTIES('serialization.null.format'='', 'skip.header.line.count'='1'); 

只需追加在您的查询属性下面的第一个标题或行intlogging将不会加载或将被跳过。

尝试这个

 tblproperties ("skip.header.line.count"="1"); 

skip.header.line.count的作品,但如果你有一些外部工具访问访问该表,它仍然会看到实际的数据,而不会跳过这些行