CSV виглядає нормально в таблиці, але після імпорту назва товару потрапляє в колонку ціни, а перший артикул не знаходиться. У навчальному сценарії причина може бути не в магазині: файл використовує крапку з комою, містить лапки або службовий маркер кодування. Перевірка CSV у Python дозволяє відокремити помилки формату від бізнес-правил ще до запису даних.
Розглянемо невеликий тестовий каталог із вигаданими товарами. Приклад не є клієнтським кейсом і не підключається до WordPress, OpenCart чи бази даних. Потрібен локальний Python 3, текстовий редактор і право читати файл. Сторонніх пакетів немає: використовуємо стандартний модуль csv. Працюйте з копією без персональних даних, не завантажуйте справжні замовлення у публічні онлайн-перевірки.
Спочатку домовтеся про формат
Відкрийте копію експорту в текстовому редакторі, а не лише в електронній таблиці. Перевірте перший рядок, роздільник та лапки навколо значень. Розширення .csv саме по собі не гарантує використання коми. Для нашого прикладу контракт простий: UTF-8, крапка з комою, три колонки sku, name, price саме в такому порядку. Назви умовні; для реального імпорту використовуйте погоджену схему.
Створіть у новому тестовому каталозі файл products.csv із наведеним вмістом і збережіть його в UTF-8. Ціни — вигадані навчальні значення, не пропозиція AriZone. Крапка з комою всередині назви спеціально залишена в лапках. Вона повинна належати одній назві, а не створювати четверту колонку. Це зручний контрольний випадок для перевірки вашого парсера.
sku;name;price
DEMO-01;"Notebook; blue";120.00
DEMO-02;Pen;35.00
Не розділяйте рядки через split(‘;’): такий прийом не враховує правила лапок і перенесення всередині поля. Не замінюйте всі роздільники в тексті глобально, адже це змінить самі назви. Якщо експортер має налаштування, зафіксуйте їх разом із тестовим файлом. Автоматичне визначення формату може допомогти дослідженню, але не замінює узгоджений контракт між двома системами.
Запустіть перевірку без імпорту
Поруч із CSV створіть check_csv.py та вставте код. Шлях обчислюється від розташування скрипту, тому він не залежить від поточного каталогу термінала. Якщо файл має іншу назву, замініть products.csv; якщо інша схема — змініть expected та перевірку sku разом. Не підставляйте випадковий шлях до продуктивних даних. Скрипт відкриває файл лише для читання й нічого не виправляє автоматично.
import csv
from pathlib import Path
path = Path(__file__).with_name("products.csv")
expected = ["sku", "name", "price"]
with path.open(encoding="utf-8-sig", newline="") as file:
reader = csv.DictReader(file, delimiter=";", strict=True)
if reader.fieldnames != expected:
raise ValueError("Unexpected CSV header")
count = 0
for row in reader:
if None in row or any(value is None for value in row.values()):
raise ValueError(f"Wrong field count near line {reader.line_num}")
if not row["sku"].strip():
raise ValueError(f"Empty SKU near line {reader.line_num}")
count += 1
print(f"Checked records: {count}")
Запустіть команду в каталозі із двома тестовими файлами. На системі, де інтерпретатор називається інакше, використайте перевірений локальний Python 3. Команда не встановлює залежностей і не потребує адміністративних прав. Для наведеного прикладу очікується повідомлення Checked records: 2. Це очікування навчального тесту, а не звіт про виконання на вашому сервері чи перевірку реального каталогу.
python3 check_csv.py
Параметр newline потрібен для коректної роботи CSV із перенесеннями рядків. DictReader бере назви колонок із заголовка; зайві поля та відсутні значення обробляються окремо. Синтаксис описаний в офіційній документації csv. Кодування utf-8-sig прибирає початковий UTF-8 BOM, якщо він є, але не перетворює файл з іншого кодування. Докладніше про цей механізм — у документації codecs.
Перевірте, що помилки справді зупиняють процес
Зробіть окрему копію навчального файлу. Змініть price у заголовку на cost: має спрацювати помилка заголовка. Потім поверніть заголовок і додайте зайве поле до другого товару: має спрацювати перевірка кількості полів. Окремо залиште sku порожнім. Після кожного тесту повертайте конкретну зміну, щоб наступна перевірка не маскувалася попередньою помилкою.
Номер reader.line_num означає фізичні рядки, прочитані парсером, а не гарантовано номер товару. Поле в лапках може містити перенесення, тому одне значення займає кілька фізичних рядків. Повідомлення в коді навмисно говорить «поблизу рядка». Для реального інструмента додайте безпечний ідентифікатор запису, але не друкуйте повні приватні дані чи секрети в журнал.
Якщо виникає UnicodeDecodeError, не додавайте errors=’ignore’ для приховування проблеми. Так можна непомітно втратити символи в назвах або ключах. Спочатку з’ясуйте кодування в джерела експорту й зробіть нову копію з погодженим форматом. Якщо файл не знайдено, перевірте назву та розміщення поруч зі скриптом. Це інша проблема, ніж неправильний роздільник, і лікувати її зміною парсера недоречно.
Формат перевірено — дані ще не готові
Успішний запуск підтверджує лише перевірки з прикладу. Він не виявляє дублікати артикулів, неправильну валюту, від’ємну ціну чи товар, якого немає в магазині. Значення залишаються рядками; число 35.00 не стає автоматично грошовою сумою. Окремо погодьте правила десяткового роздільника, валюти, порожніх полів і унікальності. Не використовуйте цю вправу як готовий продуктивний імпортер.
Перед справжнім оновленням каталогу потрібні тестове середовище, резервна копія та план відновлення конкретних змінених даних. Для роботи з локальним Python допоможе матеріал про віртуальне середовище. Збережіть маленькі контрольні CSV разом із тестами: після зміни експортера перевіряйте і правильний файл, і навмисно пошкоджені приклади, не лише відсутність аварійного завершення.
Висновок: безпечна перевірка починається з явного контракту та зупинки на невідповідності, а не з автоматичного виправлення всього файлу. Спочатку підтвердьте структуру, потім бізнес-правила, і лише після цього плануйте запис. Якщо експорт та імпорт вашого сайту розуміють колонки по-різному, AriZone може допомогти узгодити формат і перевірити інтеграцію на тестовій копії.
Залиште коментар