Stół Zewnętrzny Hive Pomiń Pierwszy Wiersz

Używam wersji Cloudera Hive i próbuję stworzyć zewnętrzną tabelę nad plikiem csv, który zawiera nazwy kolumn w pierwszej kolumnie. Oto kod, którego do tego używam.

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'

Przykładowe Dane

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

Czy ktoś może mi pomóc w pominięciu pierwszego wiersza lub czy muszę dodać krok pośredni?

Author: Rick Gittins, 2013-04-02

7 answers

Wiersze nagłówka w danych są nieustannym bólem głowy w ulu. Poza modyfikacją Źródła Ula, wierzę, że nie można uciec bez pośredniego kroku. (Edit: to już nie jest prawda, zobacz aktualizację poniżej)

Niestety, to odpowiada na twoje pytanie. Dorzucę kilka pomysłów na etap pośredni dla kompletności.

Możesz uciec bez dodatkowego kroku w ładowaniu danych, jeśli chcesz odfiltrować wiersz nagłówka na każdym zapytaniu, które dotyka tabeli. Niestety to dodaje dodatkowy zestaw prawie wszędzie indziej. I będziesz musiał uzyskać sprytny / niechlujny, gdy wiersz nagłówka narusza twój schemat. Jeśli zastosujesz takie podejście, możesz rozważyć napisanie niestandardowego SerDe, które ułatwi filtrowanie tego wiersza. Niestety, SerDe ' y nie mogą całkowicie usunąć wiersza (lub może to stanowić możliwe rozwiązanie), muszą zwrócić coś w stylu null. Nigdy nie widziałem tego podejścia w praktyce do radzenia sobie z rzędami nagłówków, ponieważ sprawia, że czytanie jest bolesne, a czytanie ma tendencję być o wiele bardziej powszechne niż pisanie. Może mieć miejsce, jeśli masz do czynienia z jedną z tabel lub jeśli wiersz nagłówka jest tylko jednym wierszem wśród wielu zniekształconych wierszy.

Możesz zrobić to filtrowanie raz z wariantami usuwania pierwszego wiersza w ładowaniu danych. Może to zrobić klauzula WHERE w INSERT. Możesz użyć narzędzi takich jak sed, aby się go pozbyć. Widziałem oba podejścia. Istnieją kompromisy pomiędzy podejściem, które przyjmujesz i nie jest to jedyny prawdziwy sposób radzenia sobie z wiersze nagłówka. Niestety, oba te podejścia wymagają czasu i wymagają tymczasowego powielania danych. Jeśli absolutnie potrzebujesz wiersza nagłówka dla innej aplikacji, powielanie będzie trwałe.

Update:

Od Hive v0. 13. 0, możesz użyć skip.nagłówek.Kolejkalicz. Możesz również określić to samo podczas tworzenia tabeli. Na przykład:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-25 13:42:01

Chociaż masz odpowiedź od Daniela, oto kilka dostosowań możliwych za pomocą 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')

Dzięki temu masz pełną kontrolę nad separatorem, znakiem cytowania, znakiem escape, obsługą null i obsługą nagłówka.

Spójrz tutaj i tutaj .

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-16 06:17:47

Po prostu dołącz właściwość poniżej w zapytaniu i pierwszy nagłówek lub linia int rekord nie zostanie załadowany lub zostanie pominięty.

Spróbuj tego

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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-27 09:33:18

Nie jestem do końca pewien, czy to działa z wierszem w formacie serde ' com.bizo.hive.serde.csv.CSVSerde 'ale myślę, że powinien być podobny do formatu wiersza rozdzielane pola zakończone przez','.
w Twoim przypadku pierwszy wiersz będzie traktowany jak normalny wiersz. Ale pierwsze pole nie jest INT, więc wszystkie pola dla pierwszego wiersza będą ustawione jako NULL. Potrzebujesz tylko jednego pośredniego kroku, aby to naprawić:

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

Jedyną wadą jest to, że oryginalny plik csv zostanie zmodyfikowany. Mam nadzieję, że to pomoże. 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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-01 22:18:06

Ja też się z tym zmagałem i nie znalazłem sposobu żeby ula pominąć pierwszy rząd, tak jak jest np. w Greenplum. Więc w końcu musiałem go usunąć z plików. np. " plik 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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-20 08:41:57

Skip.nagłówek.Kolejkacount działa, ale jeśli masz jakieś zewnętrzne narzędzie uzyskujące dostęp do tej tabeli, nadal będzie widzieć rzeczywiste dane bez pomijania tych linii

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-09 20:58:03