#Что происходит и когда возникает
Ошибка SQLite «datatype mismatch» возникает, например, когда в столбец INTEGER PRIMARY KEY (псевдоним ROWID) пытаются вставить значение, которое нельзя преобразовать в целое число. В таблицах STRICT несовместимые значения чаще вызывают «cannot store ...» (SQLITE_CONSTRAINT_DATATYPE). Обычный INTEGER без STRICT может принять текст из-за динамической типизации. Поэтому нельзя считать причиной только разделитель CSV — сначала нужно посмотреть объявление столбца и конкретную строку.
#Возможные причины: как различить
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Текст в INTEGER PRIMARY KEYВ идентификаторе CSV содержится строка «неизвестно», дробная или испорченная запись. | Ошибка возникает на конкретной строке; таблица объявляет id INTEGER PRIMARY KEY. | Проверить источник ID, не заменять его произвольным числом. |
| STRICT-таблица с несовместимым значениемSQLite требует соответствия типу, даже если обычная таблица приняла бы текст. | В sqlite_schema найдено STRICT; сообщение может отличаться от datatype mismatch. | Явно преобразовать тип после проверки данных. |
| Неверное сопоставление колонок CSVЗаголовок или порядок колонок не соответствует INSERT. | В числовой столбец попало название либо местами поменялись id и amount. | Использовать явные имена полей и проверить сопоставление до импорта. |
#Пошаговая диагностика и исправление
- Сохраните исходный CSV и прекратите повторный импортЕсли импорт уже падает, не изменяйте CSV на месте и не запускайте загрузку многократно. Создайте копию исходного файла с отдельным именем, запишите номер проблемной строки из журнала и первоначальную кодировку. Если импорт частично зафиксировал строки, выясните, где приложение начинает и завершает транзакцию.
- Посмотрите объявление таблицыОткройте консоль SQLite для тестовой копии базы. Выполните SELECT sql FROM sqlite_schema WHERE name='items'; и PRAGMA table_info(items);, заменив items именем таблицы. Ищите INTEGER PRIMARY KEY, ограничения NOT NULL и STRICT в CREATE TABLE. Если в таблице нет таких ограничений, проверьте фактическую обработку CSV приложением.
- Проверьте строку CSV как текстОткройте копию CSV в редакторе без автоматического превращения кодов в числа (например, текстовым редактором). Посмотрите, есть ли заголовок, какой разделитель используется, нет ли кавычек, пробелов, ведущих нулей и локальной десятичной запятой. Значения вида 00123 могут быть кодами, а не числами; их нельзя безусловно превращать в 123.
- Сопоставьте столбцы перед импортомВ настройках импортёра задайте явную карту: столбец CSV id → колонка id, amount → amount. Учитывайте кодировку и десятичный формат исходных данных. Отдельно отследите пустые значения и нечисловые маркеры: для допустимого отсутствия значения может быть нужен NULL, но только если так требует модель данных.
- Проверьте строку минимальным безопасным примеромЗапустите учебный сценарий из блока ниже через python3 в терминале. В нём используется только база в памяти; сначала строковый ID воспроизводит datatype mismatch, затем числовой 123 записывается успешно. Не переносите исправленное значение 123 в реальную базу: оно относится только к учебному примеру.
- Проведите пробный импорт в копиюСоздайте согласованную резервную копию, подключите отдельную тестовую базу и загружайте в транзакции сначала небольшой набор строк. Если обработчик поддерживает режим предварительного просмотра, включите его. По ошибке сохраняйте номер строки и исходный текст, затем ROLLBACK; не пропускайте ошибочные записи молча.
- Исправьте данные в источнике или правила преобразованияПроверьте с владельцем данных допустимый диапазон ID и назначение числового поля. Если это текстовый код с ведущими нулями, он должен храниться как TEXT (после согласованной миграции), а не принудительно округляться. Для действительного числового идентификатора исправьте только неверный ввод, сохраните журнал изменений и повторите импорт в копии.
#Команды и проверочные примеры
PRAGMA table_info(items);SELECT sql FROM sqlite_schema WHERE name = 'items';import sqlite3
con = sqlite3.connect(":memory:")
con.execute("CREATE TABLE demo(id INTEGER PRIMARY KEY, name TEXT)")
try:
con.execute("INSERT INTO demo(id, name) VALUES(?, ?)", ("неизвестно", "Тест"))
except sqlite3.IntegrityError as e:
print(type(e).__name__, str(e))
con.execute("INSERT INTO demo(id, name) VALUES(?, ?)", (123, "Тест"))
print(con.execute("SELECT id FROM demo").fetchall())
con.close()#Как проверить результат
Тестовый импорт завершился без ошибок, числа и коды сохранены именно в требуемом формате, количество строк до/после соответствует плану. Проверьте несколько крайних значений (пустое, 0, отрицательное, максимальное, код с нулями), а ошибочные строки вынесите в отдельный отчёт.
#Если не помогло
При повторной ошибке уточните, является ли поле INTEGER PRIMARY KEY, STRICT или содержит CHECK, сравните типы параметров в драйвере. Сохраните обезличенный пример CSV из 2–3 строк, CREATE TABLE и точный текст исключения для разработчика.