База пожимает плечами — валидатор называет имена
Провалившийся импорт редко объясняет сам себя. Загрузчик сообщает синтаксическую ошибку около такой-то строки или, того хуже, грузит половину файла и останавливается, а оператору остаётся гадать между кодировками, разделителями и стилями кавычек. Поэтому первый шаг — не починка, а диагностика — запустите структурную валидацию и получите список дефектов с номерами строк: битые строки, незакрытые кавычки, столбцы, не сходящиеся с заголовком. Файл, который валидируется чисто, но всё равно не грузится, страдает заголовками или дубликатами — ровно тем, чем занимаются следующие два шага. Файл, который валидируется грязно, сперва чинит неровные строки или сознательно их пропускает, потому что каждый следующий инструмент доверяет той структуре строк, которую ему вручили.
Заголовки — это договор
Целевая таблица — договор; первая строка файла — торг. Внешние выгрузки приходят с Customer ID в январе, userid в феврале и CUSTID всякий раз, когда отчёт делает другая команда. Разрешение заголовков отображает каждое из этих имён на настоящие столбцы целевой схемы, соединяя многослойное автосопоставление с явным словарём псевдонимов для имён, уже известных как ненадёжные. Результат этого шага — таблица соответствий, где каждый столбец схемы питается ровно от одного исходного заголовка — ничего не осталось неохваченным, ничего не оспаривается вдвоём. Неохваченный столбец обернётся тихими NULL после загрузки; оспариваемый двумя — тем, что одно поле молча затрёт другое. Оба дефекта дешевле поймать на экране сопоставления, чем в запросе три недели спустя.
Дубликаты — это решение, а не случайность
Повторные строки в файле импорта редко бывают случайностью — это повторные выгрузки, формы, отправленные дважды, или два человека, вносящие одного клиента. Поэтому дедупликация принадлежит заявленному правилу, а не рефлексу. Точное совпадение — честное значение по умолчанию — оно убирает строки, встречающиеся дважды слово в слово, и никогда не трогает те, что лишь похожи. Нечёткое заслуживает места, когда файл набран вручную и пробел или регистр разделяют настоящих близнецов — и оно обязано быть записанным, ибо «мы удалили 340 строк» защищаемо лишь тогда, когда критерий зафиксирован. Арифметика строк замыкается на этом шаге — исходные строки, минус дубликаты, минус пропущенные битые строки, равны тому, что выдаст следующий шаг.
Два выхода — проверяемые INSERT или массовый TSV
Конечный артефакт следует пути загрузки. Пакетные инструкции INSERT подходят для умеренной, проверяемой загрузки — они несут вывод типов, нацелены на MySQL, PostgreSQL, SQLite или SQL Server и объявляют стратегию конфликтов, ON CONFLICT или IGNORE, так что повторный прогон ничего не удваивает. Их можно читать на код-ревью, положить в систему контроля версий и проиграть заново по мере надобности. Выход TSV служит штатному массовому загрузчику — пути COPY и LOAD DATA поглощают чистый файл с табуляцией несравнимо быстрее любого потока инструкций, а преобразование диалекта заботится о полях в кавычках и встроенных разделителях, чтобы TSV оставался безопасным для разбора. Оговорка одна — массовый загрузчик не станет разрешать конфликты за вас, поэтому файл с возможными повторными прогонами принадлежит пути INSERT, где живёт стратегия конфликтов.
Где этот процесс останавливается
Эта страница чинит один внешний CSV, отвергнутый базой данных, и доводит его до первой успешной загрузки. Когда задача перерастает эти рамки, передайте её соседям. Источники, приходящие рабочими книгами, или передача, которая должна еженедельно идти без присмотра, — владение процесса ETL-приёма. Подозрительные значения, выбросы и доказательства качества для спора — владение исследования качества данных. Фильтрация, группировка и переформатирование таблицы, которая и так грузится, — владение процесса утилит CSV, а проектирование или миграция самой схемы — владение страниц миграции схемы базы. Почините сначала — а когда дело станет рутиной, повышьте его до конвейера.