раздел 03 · подстраница 2

Подводные камни CSV

CSV выглядит обманчиво простым: текст с запятыми, что тут сложного. На практике именно эта простота и подводит. Соберём грабли, на которые наступают все, - чтобы вы знали их в лицо.

1. Запятая внутри значения

Что будет, если в названии города есть запятая?

name,address
Анна,"Москва, ул. Ленина, 1"

Адрес взят в кавычки - и это правильный CSV: кавычки говорят «всё внутри это одно значение, запятые тут не разделители». Но если вы парсите файл наивным split(","), то получите не два поля, а четыре, и данные поедут.

2. Кодировка и кракозябры

Самая частая боль с русским текстом. Файл сохранён в одной кодировке, открыт в другой - и вместо Анна вы видите Ð�нна или ╨Р╨╜╨╜╨░.

Правила, которые спасают:

  • всегда явно указывайте encoding="utf-8" при чтении и записи;
  • для совместимости с Excel сохраняйте в utf-8-sig;
  • если читаете чужой файл и видите мусор - попробуйте кодировку cp1251 (старый русский Windows-стандарт), такие файлы ещё встречаются.

3. Нет типов данных

В CSV всё - текст. Число 007, дата 2026-01-15, булево true - для файла это просто строки.

id,price,in_stock
1,1990,true
2,0,false

При чтении price придёт как строка "1990", а не число. Сравнение, сортировка, арифметика сломаются, пока вы сами не превратите текст в число:

price = int(row["price"])     # явное преобразование, иначе будет строка

Особенно коварны ведущие нули: 007 при чтении как число станет 7, и почтовый индекс или артикул сломается. Если ведущие нули важны - держите значение строкой.

4. Нет вложенности

CSV - это плоская таблица. Один человек - одна строка - фиксированные столбцы. Как только у сущности появляется список (несколько телефонов, несколько товаров в заказе), CSV начинает страдать. Люди городят костыли: phones со значением "+7900...; +7901..." через свой разделитель, который потом надо парсить отдельно.

Это явный сигнал: данные переросли таблицу, нужен JSON (следующий раздел).

5. Разные строки - разное число столбцов

Иногда файл собирают руками или склеивают из разных источников, и строки получаются разной длины: где-то четыре поля, где-то три. Хороший парсер на этом ругнётся, плохой - молча сдвинет данные. Всегда проверяйте, что число значений в строке совпадает с числом заголовков.

6. Переносы строк внутри значения

В адресе или комментарии может быть перенос строки. В корректном CSV такое значение берётся в кавычки и занимает несколько физических строк файла, оставаясь одной логической записью. Наивное чтение «строка файла = запись» на этом ломается. Ещё одна причина пользоваться библиотекой, а не читать построчно вручную.

Когда уходить с CSV

Соберём сигналы, что CSV пора менять на JSON или базу:

  • в данных появилась вложенность (списки, объекты внутри записи);
  • важны типы и их легко перепутать (даты, числа с нулями, флаги);
  • нужно часто менять отдельные записи, а не весь файл целиком;
  • файл вырос настолько, что искать по нему стало медленно.

Антипаттерны

  • split(",") вместо библиотеки - ломается на кавычках и запятых внутри полей.
  • Доверять типам - всё в CSV текст, преобразуйте явно.
  • Запихивать вложенность через самодельные разделители - вы заново изобретаете JSON, только хуже.