Подтвердить что ты не робот

Уличная внешняя таблица Skip First Row

Я использую версию куста Cloudera и пытаюсь создать внешнюю таблицу над файлом csv, который содержит имена столбцов в первом столбце. Вот код, который я использую для этого.

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"

Может ли кто-нибудь помочь мне с тем, как пропустить первую строку или мне нужно добавить промежуточный шаг?

4b9b3361

Ответ 1

Строки заголовков в данных - это постоянная головная боль в Улье. Не дожидаясь изменения источника улья, я считаю, что вы не можете уйти без промежуточного шага. (Изменить: это больше не верно, см. Обновление ниже)

К сожалению, это отвечает на вопрос. Я сделаю несколько идей для промежуточного шага для полноты.

Вы можете уйти без дополнительного шага в загрузке данных, если вы хотите отфильтровать строку заголовка для каждого запроса, который касается таблицы. К сожалению, это добавляет дополнительный набор почти везде. И вам придется усердно/беспорядочно, когда строка заголовка нарушает вашу схему. Если вы пойдете с таким подходом, вы можете подумать о создании пользовательского SerDe, который упрощает фильтрацию этой строки. К сожалению, SerDe не может полностью удалить строку (или может создать возможное решение), они должны вернуть что-то вроде null. Я никогда не видел такого подхода, который применялся на практике для обработки строк заголовков, поскольку он делает чтение болью, и чтение, как правило, гораздо более распространено, чем запись. Это может иметь место, если вы имеете дело с одной таблицей или если строка заголовка является только одной строкой среди многих неверных строк.

Вы можете сделать эту фильтрацию один раз с изменениями при удалении этой первой строки при загрузке данных. Предложение WHERE в выражении INSERT будет делать это. Вы можете использовать утилиты, такие как sed, чтобы избавиться от него. Я видел оба подхода. Существуют компромиссы между тем, какой подход вы принимаете, и ни один из них не является истинным способом обработки строк заголовков. К сожалению, оба этих подхода требуют времени и требуют временного дублирования данных. Если вам абсолютно нужна строка заголовка для другого приложения, дублирование будет постоянным.

Update:

Из Hive v0.13.0 вы можете использовать skip.header.line.count. Вы также можете указать это при создании таблицы. Например:

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");

Ответ 2

Пока у вас есть ответ от Дэниела, вот некоторые настройки можно использовать с помощью 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')

При этом у вас есть полный контроль над разделителем, символом цитаты, символом escape, нулевой обработкой и обработкой заголовков.

Посмотрите здесь и здесь.

Ответ 3

Просто добавьте свойство ниже в свой запрос, и первый заголовок или строка int запись не будет загружена или она будет пропущена.

Попробуйте это

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

Ответ 4

Я не совсем уверен, работает ли он с 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!

Ответ 5

Я также боролся с этим и не нашел способа сказать кусту пропустить первую строку, например, например. в Гринплюме. Поэтому, наконец, мне пришлось удалить его из файлов. например "cat File.csv | grep -v RecordId > File_no_header.csv"

Ответ 6

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');

Ответ 7

skip.header.line.count работает, но если у вас есть внешний инструмент для доступа к этой таблице, он все равно увидит, что фактические данные без пропуска этих строк

Ответ 8

Просто для тех, кто уже создал таблицу с заголовком. Вот команда alter для того же. Это полезно, если у вас уже есть таблица, и вы хотите, чтобы первая строка игнорировалась без удаления и повторного создания. Это также помогает людям ознакомиться с ALTER в качестве опции с TBLPROPERTIES.

ALTER TABLE tablename SET TBLPROPERTIES ("skip.header.line.count"="1");