Проблемы с полем даты при использовании Sqoop с параметром --as-avrodatafile
Ниже приводится суть моей проблемы.
Конверт: Hadoop 2 (CDH5.1) база данных: оракул 11g
Сценарии: я помещаю таблицы фактов и измерений из базы данных в hdfs. Первоначально у меня были проблемы с обработкой пустых значений (которые были обработаны с использованием --null-string и --non-null-string), для которых было установлено значение \N согласно рекомендации. Все было хорошо, когда созданная таблица улья имела строковые поля даже для даты и чисел.
Решение до сих пор Основываясь на рекомендации, я перехожу к импорту в формате Avro. Я построил таблицу кустов на основе данных avro и могу запросить таблицы. Теперь мне нужно создать соединения Hive и преобразовать все поля в их требуемый тип, например, даты в даты / метки времени, числа в int / bigint и т. Д. После выполнения циклирования созданная схема avro преобразовала все поля даты в long и таблицу hive. показать bigint для этих столбцов.
Я запутался в том, как sqoop обрабатывает пустые значения и как они должны обрабатываться в hive/hdfs MR и т. Д.
Не могли бы вы предложить какую-либо принятую практику, которая могла бы быть использована?
Спасибо венкатеш
3 ответа
Это было проблемой и для меня. Когда я импровизировал схему из паркетных столов... в Parquet хранится метка времени как bigint. Таким образом, я думаю, что основной проблемой является паркет, у которого нет отдельного типа данных для хранения метки времени. Не используйте AVRO очень часто, но я думаю, что это верно и для AVRO. Таким образом, если вы поместите из Oracle / метку даты в набор файлов parquet / avro, то тип хранения (bigint) - это то, как оно хранится, а не то, как вы хотите получить к нему доступ (метка времени / дата).
Это время хранится в виде количества миллисекунд от времени эпохи UNIX (1 января 1970 года). Существуют функции Hive/Spark/Impala from_unixtime(), которые занимают количество секунд, поэтому решение состоит в том, чтобы преобразовать эти значения мс в разрешение s:
SELECT ..
, from_unixtime(cast(bigint_column/1000 as bigint))
Таким образом, вы увидите метки времени, такие как:
1999-04-14 06:00:00
1999-04-15 06:00:00
Обратите внимание на 6-часовую смену. В моем случае исходный тип данных Oracle был DATE без какой-либо временной части (00:00:00), но из-за моего часового пояса (MST) время менялось на 06 часов. Итак, чтобы получить точные даты:
SELECT ..
, from_unixtime(cast(bigint_column/1000 - 6*3600 as bigint))
что привело к:
1999-04-14 00:00:00
1999-04-15 00:00:00
пс. "Замечания о типах данных для паркетных столов" http://www.cloudera.com/documentation/archive/impala/2-x/2-1-x/topics/impala_parquet.html:
INT96 -> TIMESTAMP
Спасибо Гергели Подходы, которые мы использовали, чтобы преодолеть эту проблему, заключались в том, чтобы импортировать поля даты в виде строк в виде строк в формате hdf. Это было достигнуто с помощью
sqoop --option-file $OPTION_FILE_NAME \ --table $TABLE_NAME \ --map-column-java DAY_END_DTE=String \ --target-dir $TARGET_DIR \ --as-avrodatafile
Это приведет к тому, что информация о временной метке будет помещена в квадрат в виде строки формата "гггг-мм-дд чч: мм: сс.ф", которая может быть преобразована в поле даты.
это не решение, это обходной путь:
Вы можете преобразовать импортированные данные в метку времени с помощью этой команды:
выберите приведение (long_column как TIMESTAMP) из import_table;
BR, Gergely