Вывод команды Hive INSERT OVERWRITE DIRECTORY не разделяется разделителем. Зачем?

Файл, который я загружаю, разделяется символом '' (пробел). Ниже находится файл. Файл находится в HDFS: -

001 000
001 000
002 001
003 002
004 003
005 004
006 005
007 006
008 007
099 007

1 > Я создаю внешнюю таблицу и загружаю файл, выдавая следующую команду: -

CREATE EXTERNAL TABLE IF NOT EXISTS graph_edges (src_node_id STRING COMMENT 'Node ID of Source node', dest_node_id STRING COMMENT 'Node ID of Destination node') ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS TEXTFILE LOCATION '/user/hadoop/input';

2 > После этого я просто вставляю таблицу в другой файл, вызывая следующую команду: -

INSERT OVERWRITE DIRECTORY '/user/hadoop/output' SELECT * FROM graph_edges;

3 > Теперь, когда я cat файл, поля не разделяются каким-либо разделителем: -

hadoop dfs -cat /user/hadoop/output/000000_0

Вывод: -

001000
001000
002001
003002
004003
005004
006005
007006
008007
099007

Может кто-нибудь, пожалуйста, помогите мне? Почему удаляется разделитель и как разграничить выходной файл?

В команде CREATE TABLE я попробовал DELIMITED BY '\t', но затем я получаю ненужный столбец NULL.

Любые указатели помогают оценить. Я использую версию Hive 0.9.0.

Ответ 1

Проблема заключается в том, что HIVE не позволяет вам указать выходной разделитель - https://issues.apache.org/jira/browse/HIVE-634

Решением является создание внешней таблицы для вывода (с указанием спецификации разделителя) и вставка таблицы перезаписи вместо каталога.

-

Предполагая, что у вас есть /user/hadoop/input/graph _edges.csv в HDFS,

hive> create external table graph_edges (src string, dest string) 
    > row format delimited 
    > fields terminated by ' ' 
    > lines terminated by '\n' 
    > stored as textfile location '/user/hadoop/input';

hive> select * from graph_edges;
OK
001 000
001 000
002 001
003 002
004 003
005 004
006 005
007 006
008 007
099 007

hive> create external table graph_out (src string, dest string) 
    > row format delimited 
    > fields terminated by ' ' 
    > lines terminated by '\n' 
    > stored as textfile location '/user/hadoop/output';

hive> insert into table graph_out select * from graph_edges;
hive> select * from graph_out;
OK
001 000
001 000
002 001
003 002
004 003
005 004
006 005
007 006
008 007
099 007

[[email protected]] hadoop fs -get /user/hadoop/output/000000_0 .

Возвращается, как указано выше, с пробелами.

Ответ 2

Я думаю, используя функцию concat_ws, вы можете достичь своего результата;

INSERT OVERWRITE DIRECTORY '/user/hadoop/output' SELECT concat_ws (',', col1, col2) FROM graph_edges;

здесь я выбрал запятую как разделитель столбцов

Ответ 3

В то время как вопрос более 2 лет, и верхний ответ был правильным в то время, теперь можно сказать, что Hive пишет данные с разделителями в каталог.

Вот пример вывода данных с помощью традиционного разделителя ^ A:

INSERT OVERWRITE DIRECTORY '/output/data_delimited'
SELECT *
FROM data_schema.data_table

И теперь с разделителями табуляции:

INSERT OVERWRITE DIRECTORY '/output/data_delimited'
row format delimited 
FIELDS TERMINATED BY '\t'
SELECT *
FROM data_schema.data_table

Ответ 4

У меня есть другой голос.

Действительно, Hive не поддерживает пользовательский разделитель.

Но когда вы используете INSERT OVERWRITE DIRECTORY, в ваших строках есть разделители. Разделитель '\1'.

Вы можете использовать hadoop dfs -cat $file | head -1 | xxd, чтобы узнать это или получить файл с HDFS на локальный компьютер и открыть его с помощью vim. Будет некоторый char как '^ A' в вашем vim, который является разделителем.

Вернемся к вопросу. Вы можете использовать простой способ его решения.

  • По-прежнему используйте INSERT OVERWRITE DIRECTORY '/user/hadoop/output' для генерации /user/hadoop/output;

  • Создайте внешнюю таблицу, поля которой ограничены '\1':

    create external table graph_out (src string, dest string) 
    row format delimited 
    fields terminated by '\1' 
    lines terminated by '\n' 
    stored as textfile location '/user/hadoop/output';
    

Ответ 5

Вы можете предоставить разделитель при записи в каталоги

INSERT OVERWRITE DIRECTORY '/user/hadoop/output'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY
SELECT * FROM graph_edges;

Это должно сработать для вас.

Ответ 6

По умолчанию разделитель "^ A" . В языке python это "\ x01" .

Когда я хочу изменить разделитель, я использую SQL как:

SELECT col1, разделитель, col2, разделитель, col3,..., FROM table

Затем рассмотрите разделитель + "^ A" как новый разделитель.

Ответ 7

Я подозреваю, что куст на самом деле пишет contol-A в качестве деминера, но когда вы делаете кошку на экране, это не отображается вам на глаза.

Вместо этого попробуйте открыть файл в vi или загладить файл, если вы хотите увидеть его немного, и vi результат:

hadoop dfs -cat/user/hadoop/output/000000_0 | head > my_local_file.txt

vi my_local_file.txt

Вы должны уметь видеть символы ^ A.

Ответ 8

У меня была эта проблема, когда вывод результатов запроса куста должен быть ограничен линией. Запуск этой команды sed можно заменить: ^A to |

sed 's#\x01#|#g' test.log > piped_test.log

Ответ 9

Это было бы лучшим решением, я полагаю, хотя его круг вокруг пути достижения.

INSERT OVERWRITE DIRECTORY '/user/hadoop/output' SELECT src_node_id, '', dest_node_id FROM graph_edges;

Ответ 10

вы можете использовать этот параметр "поля с разделителями строк, прерванные символом '|'" , например, в вашем случае должно быть

INSERT OVERWRITE DIRECTORY '/user/hadoop/output' поля с разделителями строк с разделителями строк, прерванные '|' SELECT * FROM graph_edges;