раздел 03

CSV: данные в виде таблицы

Когда данных стало много и они однотипные - каждая запись с одними и теми же полями, - на сцену выходит CSV. Это всё ещё обычный текстовый файл, но устроенный как таблица: строки и столбцы. Его понимает любая программа и, что важно, Excel с Google Sheets.

Что это

CSV расшифровывается как Comma-Separated Values - значения, разделённые запятыми. Каждая строка файла - это строка таблицы, а запятые делят её на столбцы.

name,age,city
Анна,28,Москва
Борис,34,Казань
Вера,22,Сочи

Первая строка обычно - заголовки столбцов (name,age,city). Дальше - данные, по одной записи на строку. Открыв этот файл в Excel, вы увидите аккуратную таблицу из трёх столбцов.

Зачем это

CSV - идеальный формат, когда данные похожи на таблицу:

  • список клиентов, товаров, заказов, транзакций;
  • выгрузка из одной системы для загрузки в другую;
  • данные для анализа в Excel, Google Sheets или Python (pandas);
  • логи событий, где у каждого события одинаковый набор полей.

Главный козырь: CSV - универсальный язык обмена табличными данными. Из любой CRM, бухгалтерии, аналитики можно выгрузить CSV и открыть его где угодно.

Как это работает

Не разбирайте CSV вручную через split(",") - это работает только на простых данных и ломается на первой же запятой внутри значения. В каждом языке есть готовый инструмент.

import csv

# записать
rows = [
    {"name": "Анна", "age": 28, "city": "Москва"},
    {"name": "Борис", "age": 34, "city": "Казань"},
]
with open("people.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["name", "age", "city"])
    writer.writeheader()
    writer.writerows(rows)

# прочитать
with open("people.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["name"], row["city"])  # обращаемся по имени столбца

DictReader отдаёт каждую строку как словарь, где ключи - заголовки. Это удобно и читаемо.

Пример: накопление лога в CSV

import csv
from datetime import datetime

def log_event(action):
    with open("events.csv", "a", newline="", encoding="utf-8") as f:
        writer = csv.writer(f)
        writer.writerow([datetime.now().isoformat(), action])

log_event("login")
log_event("purchase")

Получаем файл, который потом легко открыть в Excel и построить сводную таблицу.

Где у CSV потолок

CSV отлично описывает плоскую таблицу - и совсем не умеет вложенность. Если у человека несколько телефонов, или у заказа список товаров, в одну клетку это уже не помещается. Также CSV не хранит типы: число 28 и текст "28" для него выглядят одинаково, тип придётся угадывать при чтении.

Как только данные перестают быть плоской таблицей - пора смотреть в сторону JSON. Это следующий раздел.

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

  • Парсить CSV через split(","). Сломается на значении вроде "Иванов, Иван". Используйте библиотеку.
  • Хранить в CSV вложенные данные. Списки и объекты внутри клетки - это сигнал, что нужен JSON.
  • Игнорировать кодировку. Русский текст без UTF-8 превращается в кракозябры, особенно при открытии в Excel. Подробнее - на странице про подводные камни.

Подразделы