Перейти к содержимому

Импорт каталога изнутри - файлы, сопоставление, перезапись

Разбираем импорт каталога целиком: из каких файлов он состоит, в каком порядке они разбираются, по какому ключу сопоставляются данные и что обмен перезаписывает.

Механика

Каталог приезжает на сайт не одним файлом, а целым набором. Номенклатура с разделами и свойствами лежит в одном файле, торговые предложения вместе с ценами и остатками - в другом, а картинки приходят обычными файлами рядом.

Разбор приехавших файлов идёт в фиксированном и понятном порядке. Сначала создаются разделы и товары, потом свойства и их значения, и только затем предложения, цены и складские остатки.

Ключом сопоставления во всех файлах служит внешний код записи. Он есть у раздела, у товара, у свойства и у значения списка, и именно по нему обмен решает, создавать запись или обновлять существующую.

Названия товаров при сопоставлении записей не используются платформой вовсе. Переименованный в учётной системе товар останется тем же товаром на сайте, а товар с новым внешним кодом приедет как новая позиция.

Свойства инфоблока создаются автоматически при первом же обмене каталогом. Платформа заводит их по данным файла, а тип свойства определяет по содержимому, и потом этот тип менять поздно.

Товары, которых нет в очередной выгрузке, обрабатываются по отдельной настройке обмена. Их либо деактивируют, либо оставляют как есть, и это решение принимают до первого боевого обмена.

Обмен работает небольшими шагами и хранит своё состояние между этими отдельными шагами. Большой файл разбирается за несколько запросов, а при обрыве часть данных уже в базе, и это нормальное поведение, а не порча каталога.

Главное следствие всей этой схемы очень простое: учётная система остаётся хозяином данных. Всё, что правится на сайте в полях, которые приезжают из выгрузки, живёт до следующего обмена.

Из этого правила вытекает и порядок работ на проекте. Сначала договариваются, кто и какие поля ведёт, потом настраивают обмен, и только после этого контент-менеджер начинает наполнять карточки товаров.

Отдельного внимания при таком разделении требуют картинки и метатеги. Они приезжают не всегда, и на многих проектах остаются полностью за сайтом вместе с текстами для покупателя.

Шаги

  1. Посмотреть, какие именно файлы приезжают в каталог обмена и какого они размера.
  2. Проверить внешние коды у разделов, товаров и свойств сразу на обеих сторонах.
  3. Понять, какие именно поля перезаписываются обменом, а какие остаются за сайтом.
  4. Договориться о поведении сайта для позиций, исчезнувших из очередной выгрузки.
  5. Защитить правки сайта своим кодом либо вынести их в отдельные собственные свойства.

Код

Смотрим состав приехавших файлов:

Окно терминала
ls -la /home/bitrix/www/upload/1c_catalog/ | tail -10
head -30 /home/bitrix/www/upload/1c_catalog/import.xml
grep -c '<Товар>' /home/bitrix/www/upload/1c_catalog/import.xml
# по первым строкам видно версию формата и состав выгрузки
# число товаров в файле сразу показывает, полная это выгрузка или частичная

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

Сверяем внешние коды товаров:

$rows = \CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId, 'XML_ID' => false],
false, ['nTopCount' => 20], ['ID', 'NAME'])->Fetch();
print_r($rows);
printf("всего товаров: %d\n", \CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId], []));
// товары без внешнего кода заведены руками и обменом не обновляются

Смотрим свойства, созданные обменом:

$rs = \CIBlockProperty::GetList([], ['IBLOCK_ID' => $iblockId]);
while ($p = $rs->Fetch()) {
printf("%-20s тип=%s множ=%s xml=%s\n", $p['CODE'], $p['PROPERTY_TYPE'],
$p['MULTIPLE'], $p['XML_ID']);
}
// свойства с внешним кодом созданы обменом, остальные заведены руками
// множественность свойства тоже определяется данными первой выгрузки

Свойство, созданное обменом, менять руками рискованно. Следующая выгрузка найдёт его по внешнему коду и приведёт настройки к своему представлению, а ваши правки исчезнут.

Защищаем поля сайта от перезаписи:

\Bitrix\Main\EventManager::getInstance()->addEventHandler('iblock',
'OnBeforeIBlockElementUpdate', static function (&$fields) {
if (!defined('BX_CATALOG_IMPORT')) { return; } // не обмен - не трогаем
unset($fields['PREVIEW_TEXT'], $fields['DETAIL_TEXT']); // тексты ведёт сайт
unset($fields['PREVIEW_PICTURE'], $fields['DETAIL_PICTURE']); // и картинки тоже
});

Разделение владения полями - главное решение проекта. Учётная система ведёт названия, артикулы, цены и остатки, а сайт - тексты для покупателя, картинки витрины и метатеги.

Смотрим, что произошло с исчезнувшими позициями:

// сравниваем число выключенных за сутки с обычным для этого каталога
printf("деактивировано за сутки: %d\n", \CIBlockElement::GetList([],
['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'N',
'>=TIMESTAMP_X' => date('d.m.Y', strtotime('-1 day'))], []));
// массовая деактивация после обмена почти всегда означает неполную выгрузку

Проверяем порядок разбора по журналу:

Окно терминала
grep -iE 'import|offers|price|rest' /home/bitrix/www/bitrix/catalog_export/1c_exchange.log | tail -20
grep -c 'import.xml' /home/bitrix/www/bitrix/catalog_export/1c_exchange.log
# порядок строк показывает, до какого шага дошёл обмен и где он остановился
# число вызовов шага показывает, за сколько заходов разобрался файл

Полезно один раз выписать таблицу владения полями и держать её в описании проекта. Строка «поле - кто ведёт - что будет при обмене» экономит часы споров между разработчиком, контент-менеджером и владельцем учётной системы.

Ограничения

Тип свойства после его создания обменом практически не меняется. Свойство, приехавшее строкой, не станет списком без ручной пересборки значений у всех товаров каталога.

Порядок передачи файлов задаёт учётная система, а не сайт. Цены без товаров или предложения без родителей приезжают ровно так, как их отправили, и сайт с этим ничего не сделает.

Обмен ничего не знает о ваших правках, сделанных вручную на стороне сайта. Любое поле из выгрузки он перезаписывает, и защищать нужное приходится своим обработчиком.

Удаление разделов на стороне учётной системы опасно для всего каталога на сайте. Товары исчезнувшего раздела остаются без привязки, и разбирать это приходится вручную по журналу обмена.

Полный обмен на большом каталоге стоит дорого по времени и по нагрузке. Дневные обмены делают частичными, а полный обмен выносят в отдельное ночное окно.

Типичные проблемы

Тексты, написанные контент-менеджером, исчезли после обмена.

Поля описаний приезжают из выгрузки и перезаписываются при каждом новом сеансе обмена. Владение полями делят заранее, а тексты сайта защищают отдельным обработчиком события сохранения.

После обмена каталог наполовину выключился.

Пришла неполная выгрузка, а настройка велит деактивировать отсутствующие позиции. Поведение для исчезнувших товаров согласуют до первого боевого обмена.

Один товар приехал дважды разными позициями.

В учётной системе у него сменился внешний код, и обмен создал новую запись. Внешние коды позиций на стороне учётной системы менять нельзя вообще и никогда.

Свойство приехало строкой вместо списка.

Тип свойства определился по данным самой первой выгрузки и остался таким навсегда. Структуру свойств инфоблока готовят до первого боевого обмена, а не после него.

Цены приехали, а товаров для них нет.

Файл предложений разобрался раньше файла номенклатуры или без него. Порядок передачи файлов задаёт учётная система, и его сверяют по журналу обмена.

Обмен оборвался, и каталог в промежуточном состоянии.

Разбор файла идёт шагами, и часть данных к этому моменту уже записана. Это штатное поведение: обмен повторяют, а не восстанавливают базу из копии.

Частые вопросы

По какому полю сопоставляются товары?

По внешнему коду, который приезжает из учётной системы вместе с данными. Названия и артикулы в сопоставлении не участвуют вовсе.

Почему свойства создались сами?

Обмен заводит свойства по данным файла при первом импорте каталога. Тип определяется по содержимому, поэтому структуру лучше готовить заранее.

Как защитить тексты сайта от перезаписи?

Обработчиком события сохранения, который убирает нужные поля из данных обмена. Второй путь - вести такие тексты в отдельных свойствах, которых нет в выгрузке.

Что происходит с товарами, которых нет в выгрузке?

По настройке обмена: их деактивируют или оставляют без изменений. Это решение принимают до запуска, потому что массовая деактивация заметна сразу.

Обязательно ли выгружать каталог целиком?

Нет, частичная выгрузка изменений быстрее и нагружает сайт меньше. Полный обмен оставляют для ночного окна и для восстановления после сбоев.

Смежное

Первоисточник