hive - telefono - Colmena Mesa Externa Saltar Primera Fila
telefono colmena curico (7)
Estoy usando la versión de Cloudera de Hive e intento crear una tabla externa sobre un archivo csv que contiene 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''
Data de muestra
RecordId,FirstName,LastName
1,"John","Doe"
2,"Jane","Doe"
¿Alguien puede ayudarme a omitir la primera fila o debo agregar un paso intermedio?
Las filas de encabezado en los datos son un dolor de cabeza perpetuo en Hive. Aparte de modificar la fuente de Hive, creo que no se puede escapar 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 algunas ideas para el paso intermedio para la integridad.
Puede escapar sin un paso adicional en su carga de datos si está dispuesto a filtrar la fila del encabezado en cada consulta que toque la tabla. Desafortunadamente, esto agrega un juego extra en cualquier otro lugar. Y tendrá que ponerse listo / desordenado cuando la fila del encabezado viole su esquema. Si opta por este enfoque, podría considerar escribir un SerDe personalizado que facilite el filtrado de esta fila. Desafortunadamente, SerDe''s no puede eliminar la fila por completo (o podría formar una posible solución), deben devolver algo como null
. Nunca he visto este enfoque adoptado en la práctica para lidiar con las filas de encabezados, ya que hace que la lectura sea un dolor, y la lectura tiende a ser mucho más común que la escritura. Podría tener un lugar si está tratando con una de las tablas o si la fila del encabezado es solo una fila entre muchas filas mal formadas.
Podría hacer este filtrado una vez con variaciones al eliminar esa primera fila en la carga de datos. Una cláusula WHERE
en una INSERT
lo haría. Podrías usar utilidades como sed
para deshacerte de él. He visto ambos enfoques adoptados. Hay compensaciones entre el enfoque que toma y ninguna de las dos es la única forma verdadera de lidiar con las filas de encabezado. Desafortunadamente, ambos enfoques llevan tiempo y requieren la duplicación temporal de los datos. Si necesitas absolutamente la fila del encabezado para otra aplicación, la duplicación sería permanente.
Actualizar:
Desde Hive v0.13.0, puedes usar skip.header.line.count. 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");
Mientras tienes la respuesta de Daniel, aquí hay algunas personalizaciones posibles utilizando 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 comillas, el carácter de escape, el manejo de nulos y el manejo de encabezados.
Mira here y https://issues.apache.org/jira/browse/HIVE-5795 .
No estoy seguro de si funciona con ROW FORMAT serde ''com.bizo.hive.serde.csv.CSVSerde'' pero supongo que debería ser similar a ROW FORMAT DELIMITED FIELDS TERMINATED BY '',''.
En su caso, la primera fila será tratada como una fila normal. Pero el primer campo no es 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!
Simplemente agregue la siguiente propiedad en su consulta y el primer encabezado o línea en el registro no se cargará o se omitirá.
Prueba esto
tblproperties ("skip.header.line.count"="1");
También luché con esto y no encontré la forma de decirle a Hive que salte la primera fila, como en Greenplum, por ejemplo. Así que finalmente tuve que eliminarlo de los archivos. por ejemplo, "cat File.csv | grep -v RecordId> File_no_header.csv"
skip.header.line.count funciona pero si tiene alguna herramienta externa que accede a esta tabla, seguirá viendo los datos reales sin saltar esas líneas.
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'');