Работа с данными CSV и TSV в ClickHouse
ClickHouse поддерживает импорт данных из CSV и экспорт в CSV. Поскольку CSV‑файлы могут иметь различные особенности формата, включая строки заголовков, пользовательские разделители и escape‑символы, ClickHouse предоставляет форматы и настройки для эффективной обработки всех таких вариантов.
Импорт данных из CSV‑файла
Перед импортом данных создадим таблицу с соответствующей структурой:
Чтобы импортировать данные из CSV-файла в таблицу sometable, можно передать содержимое файла напрямую в clickhouse-client через конвейер (pipe):
Обратите внимание, что мы используем FORMAT CSV, чтобы указать ClickHouse, что мы выполняем приём данных в формате CSV. В качестве альтернативы мы можем загрузить данные из локального файла с помощью предложения FROM INFILE:
Здесь мы используем конструкцию FORMAT CSV, чтобы ClickHouse мог интерпретировать формат файла. Мы также можем загружать данные напрямую из URL с помощью функции url() или из файлов в S3-хранилище с помощью функции s3().
Мы можем не указывать формат явно для file() и INFILE/OUTFILE.
В этом случае ClickHouse автоматически определит формат на основе расширения файла.
CSV-файлы с заголовками
Предположим, что наш CSV-файл содержит заголовки:
Чтобы импортировать данные из этого файла, можно использовать формат CSVWithNames:
В этом случае ClickHouse пропускает первую строку при импорте данных из файла.
Начиная с версии 23.1, ClickHouse автоматически определяет заголовки в CSV-файлах при использовании формата CSV, поэтому нет необходимости использовать CSVWithNames или CSVWithNamesAndTypes.
CSV-файлы с пользовательскими разделителями
Если в CSV-файле используется разделитель, отличный от запятой, мы можем использовать опцию format_csv_delimiter, чтобы задать соответствующий символ:
Теперь при импорте из CSV-файла символ ; будет использоваться как разделитель вместо запятой.
Пропуск строк в CSV-файле
Иногда при импорте данных из CSV-файла может потребоваться пропустить определённое количество строк. Это можно сделать с помощью опции input_format_csv_skip_first_lines:
В этом примере мы пропустим первые десять строк CSV-файла:
Файл file содержит 1k строк, но ClickHouse загрузил только 990, так как мы указали пропустить первые 10.
При использовании функции file() в ClickHouse Cloud вам потребуется выполнять команды в clickhouse client на машине, где находится файл. Другой вариант — использовать clickhouse-local для локального анализа файлов.
Обработка значений NULL в CSV-файлах
Значения NULL могут кодироваться по-разному в зависимости от приложения, которое сгенерировало файл. По умолчанию ClickHouse использует \N как представление NULL в CSV. Это поведение можно изменить с помощью опции format_csv_null_representation.
Предположим, у нас есть следующий CSV-файл:
Если мы загрузим данные из этого файла, ClickHouse будет интерпретировать Nothing как String (что корректно):
Если мы хотим, чтобы ClickHouse воспринимал Nothing как NULL, мы можем задать это с помощью следующего параметра:
Теперь значение NULL находится там, где мы его и ожидаем:
TSV‑файлы (со значениями, разделёнными табуляцией)
Формат данных с разделителями табуляции широко используется в качестве формата обмена данными. Для загрузки данных из TSV‑файла в ClickHouse используется формат TabSeparated:
Существует также формат TabSeparatedWithNames, который позволяет работать с TSV‑файлами, содержащими заголовки. Аналогично CSV, мы можем пропустить первые X строк с помощью опции input_format_tsv_skip_first_lines.
Необработанный TSV
Иногда TSV‑файлы сохраняются без экранирования табуляций и символов перевода строки. Для обработки таких файлов следует использовать TabSeparatedRaw.
Экспорт в CSV
Любой формат, использованный в наших предыдущих примерах, можно также использовать для экспорта данных. Чтобы экспортировать данные из таблицы (или результата запроса) в формат CSV, мы используем ту же конструкцию FORMAT:
Чтобы добавить строку заголовка в CSV‑файл, используем формат CSVWithNames:
Сохранение экспортированных данных в CSV‑файл
Чтобы сохранить экспортированные данные в файл, можно использовать конструкцию INTO...OUTFILE:
Обратите внимание, что ClickHouse потребовалась всего ~1 секунда, чтобы сохранить 36 млн строк в файл CSV.
Экспорт CSV с пользовательскими разделителями
Если мы хотим использовать разделители, отличные от запятых, мы можем воспользоваться параметром format_csv_delimiter в настройках:
Теперь ClickHouse будет использовать | в качестве разделителя в формате CSV:
Экспорт CSV для Windows
Если нам нужен файл CSV, корректно работающий в среде Windows, следует включить настройку output_format_csv_crlf_end_of_line. В этом случае в качестве символов конца строки будет использоваться \r\n вместо \n:
Автоматическое определение схемы для файлов CSV
Во многих случаях нам приходится работать с неизвестными CSV-файлами, поэтому необходимо определить, какие типы данных использовать для столбцов. По умолчанию ClickHouse пытается определить форматы данных на основе анализа заданного CSV-файла. Это называется «автоматическим определением схемы». Обнаруженные типы данных можно изучить с помощью оператора DESCRIBE в сочетании с функцией file():
Здесь ClickHouse смог эффективно угадать типы столбцов для нашего CSV-файла. Если мы не хотим, чтобы ClickHouse делал это, мы можем отключить эту возможность с помощью следующей опции:
Во всех столбцах тип данных будет интерпретироваться как String.
Экспорт и импорт CSV с явным указанием типов столбцов
ClickHouse также позволяет явно задавать типы столбцов при экспорте данных с помощью формата CSVWithNamesAndTypes (и других форматов семейства WithNames):
Этот формат включает две строки заголовка — одну с именами столбцов и другую с их типами. Это позволяет ClickHouse (и другим приложениям) определять типы столбцов при загрузке данных из подобных файлов:
Теперь ClickHouse определяет типы столбцов по (второй) строке заголовка, а не пытается их угадывать.
Пользовательские разделители, сепараторы и правила экранирования
В сложных случаях текстовые данные могут быть отформатированы в сильно кастомизированном виде, но при этом сохранять структуру. В ClickHouse есть специальный формат CustomSeparated для таких случаев, который позволяет задавать собственные правила экранирования, разделители, разделители строк и начальные/конечные символы.
Предположим, что у нас есть следующие данные в файле:
Мы видим, что отдельные записи заключены в row(), строки разделены запятыми (,), а отдельные значения внутри строк — точкой с запятой (;). В этом случае мы можем использовать следующие настройки для чтения данных из этого файла:
Теперь мы можем загрузить данные из нашего файла file с пользовательским форматом:
Мы также можем использовать CustomSeparatedWithNames, чтобы корректно экспортировать и импортировать заголовки. Изучите форматы regex and template для работы с ещё более сложными случаями.
Работа с большими CSV‑файлами
CSV‑файлы могут быть большими, и ClickHouse эффективно работает с файлами любого размера. Крупные файлы обычно бывают сжаты, и ClickHouse умеет работать с ними без предварительной распаковки. Мы можем использовать предложение COMPRESSION при вставке:
Если клауза COMPRESSION опущена, ClickHouse всё равно попытается определить тип сжатия файла по его расширению. Тем же способом можно экспортировать файлы непосредственно в сжатые форматы:
В результате будет создан сжатый файл data_csv.csv.gz.
Другие форматы
ClickHouse поддерживает множество форматов, как текстовых, так и бинарных, чтобы охватить различные сценарии и платформы. Узнайте больше о форматах и способах работы с ними в следующих статьях:
- Форматы CSV и TSV
- Parquet
- Форматы JSON
- Регулярные выражения и шаблоны
- Нативные и бинарные форматы
- SQL-форматы
Также ознакомьтесь с clickhouse-local — переносимым полнофункциональным инструментом для работы с локальными и удалёнными файлами без необходимости в сервере ClickHouse.