Spec-Zone.ru › DuckDB

Чтение некорректных файлов CSV

Файлы CSV могут иметь самые разные форматы, и некоторые из них содержат множество ошибок, что затрудняет их чистое чтение. Чтобы помочь пользователям читать такие файлы, DuckDB поддерживает подробные сообщения об ошибках, возможность пропускать некорректные строки и возможность сохранения некорректных строк во временной таблице для упрощения этапа очистки данных.

Структурные ошибки

DuckDB поддерживает обнаружение и пропуск нескольких различных структурных ошибок. В этом разделе мы рассмотрим каждую ошибку с примером. Для примеров рассмотрим следующую таблицу:

CREATE TABLE people (name VARCHAR, birth_date DATE);

DuckDB обнаруживает следующие типы ошибок:

  • CAST: Ошибки приведения типов возникают, когда столбец в файле CSV не может быть приведен к ожидаемому типу схемы. Например, строка Pedro,The 90s вызовет ошибку, так как строку The 90s нельзя привести к дате.
  • MISSING COLUMNS: Эта ошибка возникает, если строка в файле CSV содержит меньше столбцов, чем ожидалось. В нашем примере ожидается два столбца; следовательно, строка с одним значением, например Pedro, вызовет эту ошибку.
  • TOO MANY COLUMNS: Эта ошибка возникает, если строка в файле CSV содержит больше столбцов, чем ожидалось. В нашем примере любая строка с более чем двумя столбцами вызовет эту ошибку, например, Pedro,01-01-1992,pdet.
  • UNQUOTED VALUE: Значения в кавычках в строках CSV всегда должны быть не в кавычках в конце; если значение в кавычках остается в кавычках на протяжении всей строки, это вызовет ошибку. Например, предположим, что наш сканер использует quote='"', строка "pedro"holanda, 01-01-1992 будет содержать ошибку невыведенного значения.
  • LINE SIZE OVER MAXIMUM: В DuckDB есть параметр, который устанавливает максимальный размер строки в файле CSV, который по умолчанию установлен в 2,097,152 байт. Предположим, что наш сканер установлен на max_line_size = 25, строка Pedro Holanda, 01-01-1992 вызовет ошибку, так как она превышает 25 байт.
  • INVALID UNICODE: DuckDB поддерживает только строки UTF-8; следовательно, строки, содержащие символы, не являющиеся UTF-8, будут вызывать ошибку. Например, строка pedro\xff\xff, 01-01-1992 будет проблематичной.

Структура сообщения об ошибке CSV

По умолчанию, при чтении CSV, если встречаются какие-либо структурные ошибки, сканер немедленно остановит процесс сканирования и выведет ошибку пользователю. Эти ошибки разработаны для предоставления максимально возможной информации, чтобы пользователи могли напрямую оценить их в своём файле CSV.

Это пример полного сообщения об ошибке:

Conversion Error: CSV Error on Line: 5648
Original Line: Pedro,The 90s
Error when converting column "birth_date". date field value out of range: "The 90s", expected format is (DD-MM-YYYY)

Column date is being converted as type DATE
This type was auto-detected from the CSV file.
Possible solutions:
* Override the type for this column manually by setting the type explicitly, e.g. types={'birth_date': 'VARCHAR'}
* Set the sample size to a larger value to enable the auto-detection to scan more values, e.g. sample_size=-1
* Use a COPY statement to automatically derive types from an existing table.

  file= people.csv
  delimiter = , (Auto-Detected)
  quote = " (Auto-Detected)
  escape = " (Auto-Detected)
  new_line = \r\n (Auto-Detected)
  header = true (Auto-Detected)
  skip_rows = 0 (Auto-Detected)
  date_format = (DD-MM-YYYY) (Auto-Detected)
  timestamp_format =  (Auto-Detected)
  null_padding=0
  sample_size=20480
  ignore_errors=false
  all_varchar=0

Первый блок предоставляет информацию о месте возникновения ошибки, включая номер строки, исходную строку CSV и проблемный столбец:

Conversion Error: CSV Error on Line: 5648
Original Line: Pedro,The 90s
Error when converting column "birth_date". date field value out of range: "The 90s", expected format is (DD-MM-YYYY)

Второй блок предоставляет потенциальные решения:

Column date is being converted as type DATE
This type was auto-detected from the CSV file.
Possible solutions:
* Override the type for this column manually by setting the type explicitly, e.g. types={'birth_date': 'VARCHAR'}
* Set the sample size to a larger value to enable the auto-detection to scan more values, e.g. sample_size=-1
* Use a COPY statement to automatically derive types from an existing table.

Поскольку тип этого столбца был определён автоматически, предлагается определить столбец как VARCHAR или полностью использовать набор данных для определения типа.

Наконец, последний блок представляет некоторые параметры, используемые в сканере, которые могут вызывать ошибки, указывая, были ли они определены автоматически или установлены пользователем вручную.

Использование параметра ignore_errors

Существуют случаи, когда файлы CSV могут содержать несколько структурных ошибок, и пользователи просто хотят пропустить их и прочитать корректные данные. Чтение файлов CSV с ошибками возможно с помощью параметра ignore_errors. При использовании этого параметра строки, содержащие данные, которые в противном случае вызвали бы ошибку анализатора CSV, будут пропущены. В нашем примере мы продемонстрируем ошибку приведения типов, но обратите внимание, что любая из ошибок, описанных в разделе «Структурные ошибки», приведет к пропусканию некорректной строки.

Например, рассмотрим следующий файл CSV, faulty.csv:

Pedro,31
Oogie Boogie, three

Если вы читаете файл CSV, указав, что первый столбец является VARCHAR, а второй столбец - INTEGER, загрузка файла завершится с ошибкой, так как строка three не может быть преобразована в INTEGER.

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

FROM read_csv('faulty.csv', columns = {'name': 'VARCHAR', 'age': 'INTEGER'});

Однако, при ignore_errors установленной, вторая строка файла пропускается, выводит только полную первую строку. Например:

FROM read_csv(
    'faulty.csv',
    columns = {'name': 'VARCHAR', 'age': 'INTEGER'},
    ignore_errors = true
);

Вывод:

name age
Pedro 31

Следует отметить, что анализатор CSV подвержен оптимизации сжатия проекции. Следовательно, если мы выберем только столбец «имя», обе строки будут считаться корректными, так как ошибка приведения типов для столбца «возраст» никогда не произойдёт. Например:

SELECT name
FROM read_csv('faulty.csv', columns = {'name': 'VARCHAR', 'age': 'INTEGER'});

Вывод:

name
Pedro
Oogie Boogie

Получение некорректных строк CSV

Возможность чтения файлов CSV с ошибками важна, но для многих операций очистки данных также необходимо точно знать, какие строки повреждены и какие ошибки обнаружил анализатор. В таких ситуациях можно использовать функцию DuckDB «Таблица отклонений CSV». По умолчанию эта функция создаёт две временные таблицы.

  1. reject_scans: Содержит информацию о параметрах сканера CSV
  2. reject_errors: Содержит информацию о каждой некорректной строке CSV и о том, в каком сканере CSV она произошла.

Обратите внимание, что любые ошибки, описанные в разделе «Структурные ошибки», будут храниться в таблицах отклонений. Также, если у строки есть несколько ошибок, будет храниться несколько записей для одной строки, по одной на каждую ошибку.

Таблицы отклонений сканирования

Таблица отклонений сканирования CSV возвращает следующую информацию:

Имя столбца Описание Тип
scan_id Внутренний идентификатор, используемый в DuckDB для представления сканера UBIGINT
file_id Сканирование может происходить по нескольким файлам, поэтому file_id представляет уникальный файл в сканере UBIGINT
file_path Путь к файлу VARCHAR
delimiter Разделитель, например; VARCHAR
quote Знак кавычек, например " VARCHAR
escape Знак кавычек, например " VARCHAR
newline_delimiter Разделитель новой строки, например \r\n VARCHAR
skip_rows Если какие-либо строки были пропущены из начала файла UINTEGER
has_header Если файл имеет заголовок BOOLEAN
columns Схема файла (т.е. все имена и типы столбцов) VARCHAR
date_format Формат, используемый для дат VARCHAR
timestamp_format Формат, используемый для временных меток VARCHAR
user_arguments Дополнительные параметры сканера, установленные пользователем вручную VARCHAR

Таблицы отклонений ошибок

Таблица отклонений ошибок CSV возвращает следующую информацию:

Имя столбца Описание Тип
scan_id Внутренний идентификатор, используемый в DuckDB для представления сканера, используется для объединения с таблицами отбракованных сканирований UBIGINT
file_id Поле file_id представляет собой уникальный файл в сканере, используется для объединения с таблицами отбракованных сканирований UBIGINT
line Номер строки в файле CSV, где произошла ошибка. UBIGINT
line_byte_position Позиция байта начала строки, где произошла ошибка. UBIGINT
byte_position Позиция байта, где произошла ошибка. UBIGINT
column_idx Если ошибка произошла в определенном столбце, индекс столбца. UBIGINT
column_name Если ошибка произошла в определенном столбце, имя столбца. VARCHAR
error_type Тип ошибки, которая произошла. ENUM
csv_line Исходная строка CSV. VARCHAR
error_message Сообщение об ошибке, сгенерированное DuckDB. VARCHAR

Параметры

Ниже перечислены параметры, используемые в функции read_csv для настройки таблицы отбракованных CSV.

Имя Описание Тип Значение по умолчанию
store_rejects Если установлено в true, все ошибки в файле будут пропущены и сохранены в стандартных временных таблицах отбракованных данных. BOOLEAN False
rejects_scan Имя временной таблицы, в которой хранится информация о сканировании некорректного CSV-файла. VARCHAR reject_scans
rejects_table Имя временной таблицы, в которой хранится информация о некорректных строках CSV-файла. VARCHAR reject_errors
rejects_limit Верхний предел количества некорректных записей из CSV-файла, которые будут записаны в таблицу отбракованных данных. 0 используется, если ограничение применять не нужно. BIGINT 0

Чтобы сохранить информацию о некорректных строках CSV-файла в таблице отбракованных данных, пользователю необходимо установить параметр store_rejects в значение true. Например:

FROM read_csv(
    'faulty.csv',
    columns = {'name': 'VARCHAR', 'age': 'INTEGER'},
    store_rejects = true
);

Затем можно запросить обе таблицы reject_scans и reject_errors, чтобы получить информацию об отброшенных кортежах. Например:

FROM reject_scans;

Вывод:

scan_id file_id путь_к_файлу разделитель кавычки экранирование разделитель_строк пропуск_строк имеет_заголовок столбцы формат_даты формат_временной_метки пользовательские_аргументы
5 0 faulty.csv , " " \n 0 false {'name': 'VARCHAR','age': 'INTEGER'} store_rejects=true
FROM reject_errors;

Вывод:

scan_id file_id строка позиция_байта_строки позиция_байта индекс_столбца имя_столбца тип_ошибки строка_csv сообщение_об_ошибке
5 0 2 10 23 2 возраст CAST Oogie Boogie, three Ошибка при преобразовании столбца "возраст". Не удалось преобразовать строку " three" в 'INTEGER'

© Copyright 2018–2024 Stichting DuckDB Foundation
Licensed under the MIT License.
https://duckdb.org/docs/data/csv/reading_faulty_csv_files.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API