Tabla Externa de Colmena Saltar Primera Fila


Estoy usando la versión de Cloudera de Hive e intentando crear una tabla externa sobre un archivo csv que contenga los nombres de columna en la primera columna. Aquí está el código que estoy usando para hacer eso.

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'

Datos de muestra

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

¿Puede alguien ayudarme a saltarme la primera fila o necesito añadir un paso intermedio?

Author: Rick Gittins, 2013-04-02

7 answers

Las filas de encabezado en los datos son un dolor de cabeza perpetuo en la colmena. A falta de modificar la fuente de la colmena, creo que no puedes salirte con la tuya sin un paso intermedio. (Editar: Esto ya no es cierto, ver actualización a continuación)

Desafortunadamente, eso responde a tu pregunta. Voy a lanzar en algunas ideas para el paso intermedio para completar.

Puede escapar sin un paso adicional en su carga de datos si está dispuesto a filtrar la fila de encabezado en cada consulta que toque la tabla. Desafortunadamente esto agrega un conjunto adicional en casi todas partes. Y usted tendrá que conseguir inteligente / desordenado cuando la fila de encabezado viola su esquema. Si opta por este enfoque, podría considerar escribir un SerDe personalizado que haga que esta fila sea más fácil de filtrar. Desafortunadamente, SerDe no puede eliminar la fila por completo (o eso podría formar una posible solución), deben devolver algo como null. Nunca he visto este enfoque tomado en la práctica para lidiar con las filas de encabezado, ya que hace que la lectura sea un dolor, y la lectura tiende ser mucho más común que escribir. Podría tener un lugar si está tratando con una de las tablas o si la fila de encabezado es solo una fila entre muchas filas malformadas.

Puede hacer este filtrado una vez con variaciones al eliminar esa primera fila en la carga de datos. Una cláusula WHERE en una sentencia INSERT lo haría. Puedes usar utilidades como sed para deshacerte de él. He visto ambos enfoques. Hay compensaciones entre el enfoque que toma y ninguna es la única manera verdadera de lidiar con filas de encabezado. Lamentablemente, ambos enfoques llevan tiempo y requieren una duplicación temporal de los datos. Si necesita absolutamente la fila de encabezado para otra aplicación, la duplicación sería permanente.

Actualización:

Desde Hive v0.13.0, puede usar skip.cabecera.alinear.contar. También puede especificar lo mismo al crear la tabla. Por ejemplo:

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");
 61
Author: Daniel Koverman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-25 13:42:01

Mientras tienes tu respuesta de Daniel, aquí hay algunas personalizaciones posibles usando 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')

Con esto, tiene control total sobre el separador, el carácter de comilla, el carácter de escape, el manejo de nulos y el manejo de encabezado.

Mirada aquí y aquí.

 8
Author: Nirmal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-16 06:17:47

Simplemente agregue la siguiente propiedad en su consulta y el primer encabezado o línea en el registro no se cargará o se saltará.

Prueba esto

tblproperties ("skip.header.line.count"="1");
 6
Author: Manish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-27 09:33:18

No estoy muy seguro de si funciona con el FORMATO DE FILA serde 'com.bizo.colmena.serde.csv.CSVSerde ' pero supongo que debería ser similar a LOS CAMPOS DELIMITADOS CON FORMATO DE FILA TERMINADOS POR ','.
En su caso, la primera fila se tratará como fila normal. Pero el primer campo no puede ser INT, por lo que todos los campos, para la primera fila, se establecerán como NULL. Solo necesitas un paso intermedio para arreglarlo:

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

Solo un inconveniente es que su archivo csv original será modificado. Espero que ayude. ¡GL!

 1
Author: www,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-01 22:18:06

También luché con esto y no encontré manera de decirle a hive que saltara la primera fila, como por ejemplo en Greenplum. Así que finalmente tuve que eliminarlo de los archivos. por ejemplo, " Archivo cat.csv / grep-v recordId > File_no_header.csv "

 1
Author: Atanas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-26 12:46:24
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');
 1
Author: Aman Mundra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-20 08:41:57

Skip.cabecera.alinear.count funciona, pero si tiene alguna herramienta externa accediendo a esta tabla , todavía verá los datos reales sin saltar esas líneas

 1
Author: itsavy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-09 20:58:03