Ошибка Sqoop --split-by при импорте, несмотря на наличие первичного ключа в таблице

Таблица MySQL с dept_id в качестве первичного ключа

|dept_id | dept_name |  
| 2 | Fitness   
| 3 | Footwear  
| 4 | Apparel   
| 5 | Golf      
| 6 | Outdoors  
| 7 | Fan Shop  

Запрос Sqoop

sqoop import \  
-m 2 \  
--connect "jdbc:mysql://quickstart.cloudera:3306/retail_db" \  
--username retail_dba \  
-P \  
--query 'select * from departments where dept_id < 6  AND $CONDITIONS' \      
--target-dir /user/cloudera/sqoop_import/departments;

Результаты с ошибкой на консоли:

При параллельном импорте результатов запроса необходимо указать --split-by

---Вопрос!---
Несмотря на то, что в таблице есть первичный ключ и разбиения могут быть поровну распределены между двумя картографами, тогда зачем нужен --spit-by или -m 1 ??

Направь меня к тому же.
Спасибо.


person Vineet Jhaveri    schedule 11.08.2016    source источник


Ответы (3)


Это не первичный ключ с использованием --split-by. вы видите ошибку из-за использования опции --query. Этот параметр ДОЛЖЕН использоваться с --split-by, --target-dir и $CONDITIONS в запросе.

документация free_form_query_imports

При импорте запроса в произвольной форме вы должны указать каталог назначения с --target-dir.

Если вы хотите импортировать результаты запроса параллельно, то каждая задача сопоставления должна будет выполнить копию запроса с результатами, разделенными по граничным условиям, выведенным Sqoop. Ваш запрос должен включать токен $CONDITIONS, который каждый процесс Sqoop заменит уникальным выражением условия. Вы также должны выбрать столбец разделения с --split-by.

Вы можете использовать опцию --where, если не хотите использовать --split-by и --query:

sqoop import \
  --connect "jdbc:mysql://quickstart.cloudera:3306/retail_db" \
  --username=retail_dba \
  -P \
  --table departments \
  --target-dir /user/cloudera/departments \
  -m 2 \
  --where "department_id < 6"

если вы используете опцию --boundary-query, вам не нужны опции --split-by, --query:

sqoop import \
  --connect "jdbc:mysql://quickstart.cloudera:3306/retail_db" \
  --username=retail_dba \
  -P \
  --table departments \
  --target-dir /user/cloudera/departments \
  -m 2 \
  --boundary-query "select 2, 6 from departments limit 1" 

выбор_the_data_to_import

По умолчанию sqoop будет использовать запрос select min(<split-by>), max(<split-by>) from <table name>, чтобы узнать границы для создания разбиений. В некоторых случаях этот запрос не самый оптимальный, поэтому вы можете указать любой произвольный запрос, возвращающий два числовых столбца, используя аргумент --boundary-query.

person Ronak Patel    schedule 12.08.2016
comment
добавление уже отвеченного ответа с более причудливыми (не относящимися к вопросу) деталями. Дайте мне знать, если вы хотите больше голосов или награду ..: D - person Dev; 12.08.2016
comment
@devツ - Спасибо, любые отзывы приветствуются и ценятся. Когда я прочитал ваш ответ, он был направлен на документы по дрели и не объяснял конкретно необходимые параметры для параметра --query. Я добавил дополнительные параметры в качестве альтернативных параметров в контексте параметров --split-by и --query, чтобы пользователь мог видеть разницу в том, что невозможно использовать --split-by с импортом таблицы с первичным ключом и картографом › 1 с этими параметрами (я нашел это уместным, на мой взгляд) - еще раз спасибо :) - person Ronak Patel; 12.08.2016
comment
BTW Drill был опечаткой, которую я исправил, документы ссылаются на те же документы sqoop. - person Dev; 12.08.2016

Причина, по которой для импорта Sqoop требуется --split-by при использовании --query, заключается в том, что когда вы указываете исходное местоположение данных в «запросе», невозможно узнать/угадать первичный ключ для Sqoop. Потому что в запросе вы можете объединить две или более таблиц, которые будут иметь несколько ключей и полей. Таким образом, Sqoop не может знать/догадываться, по какому из этих ключей он может быть разделен.

person grepIt    schedule 25.11.2016

Согласно документам sqoop,

Если вы хотите импортировать результаты запроса параллельно, то каждая задача сопоставления должна будет выполнить копию запроса с результатами, разделенными по граничным условиям, выведенным Sqoop. Ваш запрос должен включать токен $CONDITIONS, который каждый процесс Sqoop заменит уникальным выражением условия. Вы также должны выбрать столбец разделения с --split-by.

Поэтому вам нужно указать свой первичный ключ в теге --split-by.

Если вы выберете 1 маппер, Sqoop не будет разделять задачи параллельно и выполнит полный импорт в 1 маппер.

Проверьте мой другой ответ (если хотите), чтобы понять потребность в $CONDITIONS и количестве картографов.

person Dev    schedule 11.08.2016