Как выгрузить таблицу на RedShift в один файл CSV?
Я хочу перенести таблицу из Amazon RedShift в MySQL, но с помощью "unload" будет создано несколько файлов данных, которые трудно импортировать в MySQL напрямую.
Есть ли какой-либо подход для выгрузки таблицы в один файл CSV, чтобы я мог напрямую импортировать его в MySQL?
Ответы
Ответ 1
Чтобы отправить в один файл, используйте параллельное выключение
unload ('select * from venue')
to 's3://mybucket/tickit/unload/venue_' credentials
'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>'
parallel off;
Также я рекомендую использовать Gzip, чтобы сделать этот файл еще меньше для загрузки.
unload ('select * from venue')
to 's3://mybucket/tickit/unload/venue_' credentials
'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>'
parallel off
gzip;
Ответ 2
На данный момент это старый вопрос, но я чувствую, что все существующие ответы немного вводят в заблуждение. Если у вас есть вопрос: "Могу ли я абсолютно 100% гарантировать, что Redshift ВСЕГДА будет выгружаться в SINGLE файл в S3?", Ответ просто НЕТ.
При этом в большинстве случаев вы можете ограничить свой запрос таким образом, чтобы в итоге вы попали в один файл. В документации (https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD.html) основным фактором ограничения количества файлов, которые вы создаете, является фактический размер необработанного размера в байтах вашего экспорта (NOT количество строк). Предел размера файла вывода, созданного командой Redshift UNLOAD
составляет 6,2 ГБ.
Поэтому, если вы хотите попытаться гарантировать, что вы получите один выходной файл из UNLOAD
, вот что вы должны попробовать:
- Укажите
PARALLEL OFF
. Параллельно по умолчанию включено "ВКЛ" и, как правило, записывается в несколько файлов, если у вас нет крошечного кластера (количество выходных файлов с параметром "PARALLEL ON" пропорционально количеству срезов в вашем кластере). PARALLEL OFF
будет записывать файлы поочередно на S3, а не параллельно, и будет только переходить на использование нескольких файлов, если вы превысите ограничение по размеру. - Ограничьте размер вашего вывода. Необработанный размер данных должен быть меньше 6,2 ГБ, если вы хотите использовать один файл. Поэтому вам нужно, чтобы ваш запрос имел более ограничительное
WHERE
или использовал предложение LIMIT
, чтобы уменьшить количество записей. К сожалению, ни один из этих методов не идеален, поскольку строки могут иметь переменный размер. Мне также непонятно, может ли параметр GZIP
влиять на ограничение распространения потока выходного файла или нет (неясно, является ли 6.2GB пределом размера до GZIP или пределом размера после GZIP).
Для меня команда UNLOAD, которая в конечном итоге завершает создание одного файла CSV, в большинстве случаев:
UNLOAD
('SELECT <fields> FROM <table> WHERE <restrict_query>')
TO 's3://<bucket_name>/<filename_prefix>'
CREDENTIALS 'aws_access_key_id=<access_key>;aws_secret_access_key=<secret_key>'
DELIMITER AS ','
ADDQUOTES
NULL AS ''
PARALLEL OFF;
Другим приятным побочным эффектом PARALLEL OFF
является то, что он будет уважать ваше предложение ORDER BY
, если оно у вас есть, и сгенерировать файлы в порядке, который хранит все записи, даже в нескольких выходных файлах.
Добавление: Кажется, есть некоторые фольклорные знания вокруг использования LIMIT 2147483647
чтобы заставить лидерский узел выполнять всю обработку и генерировать один выходной файл, но это, похоже, не документируется нигде в документации Redshift и как таковая, полагаясь по-видимому, это плохая идея, поскольку она может измениться в любое время.
Ответ 3
Это немного обходное решение, но вам нужно сделать запрос подзапросом и включить ограничение. Затем он будет выводиться в один файл. Например
select * from (select * from bizdata LIMIT 2147483647);
Поэтому в основном вы выбираете все из ограниченного набора. Это единственный способ, которым это работает. 2147483647 - ваш максимальный предел, поскольку предложение limit принимает аргумент целочисленного значения без знака.
Таким образом, следующее будет выгружено в один файл:
unload(' select * from (
select bizid, data
from biztable
limit 2147483647);
') to 's3://.......' CREDENTIALS 'aws_access_key_id=<<aws_access_key_id>>;aws_secret_access_key=<<aws_secret_access_key>>' csv ;
Ответ 4
Неа. {Вы можете использовать манифест и сообщить Redshift, чтобы направлять весь вывод в один файл. } Предыдущий ответ был неправильным, я использовал манифесты для загрузки, но не для разгрузки.
Кажется, есть два возможных способа получить один файл:
- Легче: обмотайте запрос SELECT... LIMIT вокруг вашего фактического выходного запроса, согласно этому ответу SO, но это ограничено ~ 2 миллиардами строк.
- Harder: используйте утилиту
cat
для Unix, чтобы объединить файлы вместе с cat File1.txt File2.txt > union.txt
. Это потребует, чтобы вы сначала загрузили файлы с S3.
Ответ 5
Невозможно заставить Redshift генерировать только один выходной файл.
В стандартном UNLOAD вы создадите выходные файлы, эквивалентные количеству системных срезов, то есть система с 8 срезами создаст 8 файлов для одной команды unload (это самый быстрый способ для разгрузки).
Если вы добавите предложение PARALLEL OFF в команду "Unload Command", ваш вывод будет создан как один файл, до того момента, когда вырезка данных не будет превышать 6,25 ГБ, после чего Redshift автоматически разбивает файл на новый фрагмент,
То же самое верно, если вы также создаете сжатые выходные файлы (конечно, у вас будет больше шансов создать один выходной файл, учитывая, что ваш файл может разместить в нем больше количества записей).