Миграция данных: переезд

Как завезти данные из старой системы и не сломать дом. Модули: 6.16.26.36.47.9. Подробно с реальными ловушками: kb/migration/.

1. Миграция это проект, а не кнопка

Загрузить CSV можно за минуту. Неделями занимает всё остальное: решить, что переносить, перевести поля и значения, почистить, проверить, что перенеслось ровно то, что нужно. Цикл «загрузил, сверил, поправил» повторяется несколько раз в sandbox, прежде чем данные пойдут в production.

1 Scopeчто переносим,критерии отбора 2 Выгрузкаиз самого свежегоисточника 3 Mappingполе в поле,значение в значение 4 Чисткадубли, пустые,кривые значения 5 Тест-загрузкав sandbox, с bypassавтоматизации 6 Сверкаколичества и суммыдо и после 7 Исправленияправим правило,не данные руками 8 Cutoverфинальная загрузкав окно переключения 9 Приёмкаклиент подписалрезультат сверки Журналкаждая странностьисточникас доказательством повтор цикла Журнал ведётся с первого дня: он защищает сроки и объём работ, когда клиент спрашивает «почему так долго»

Шаги 5-7 крутятся несколько раз. Правило: исправляют правило преобразования и грузят заново, а не правят записи руками после загрузки.

2. Порядок загрузки: сначала родители

Ребёнок не может сослаться на родителя, которого ещё нет. Поэтому объекты грузят слоями. Users, record types и значения picklist обычно не грузят, а сопоставляют по таблице соответствий.

слой 0: сопоставитьслой 1слой 2слой 3проверка Usersвладельцы по email Record typesи picklists по имени Accountключ Legacy_Id__c Product2ProductCode ContactAccount по ключу OpportunityAccount по ключу PricebookEntryпродукт и прайс-лист OpportunityLineItemсделка и цена Сверкаcounts и суммыпо каждому слою

У каждой загружаемой записи свой ключ из старой системы (External ID). По нему ребёнок находит родителя без знания новых Salesforce Id.

3. External ID и upsert: защита от дублей

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

accounts.csv Legacy_Id__c,NameL1001,Northwind TradingL1002,Blue Harbor Ltd upsertпо Legacy_Id__c L1001 уже естьзапись обновлена (update) L1002 нетзапись создана (insert) contacts.csv LastName,Account.Legacy_Id__cRivera,L1001 AccountId подставится самзагрузчик находит Account с Legacy_Id__c = L1001 и берёт его Salesforce Id

В CSV для Bulk API и sf data import колонка ссылки называется Account.Legacy_Id__c. В Data Loader то же самое выбирается на шаге связанных объектов при upsert.

4. Переезд в Revenue Cloud: что грузить, а что строит платформа

В Revenue Cloud часть записей нельзя загрузить вообще: историю актива (AssetAction, AssetStatePeriod) строит движок, когда активируют order. Поэтому работают так: загружают заказы черновиками, проверяют до активации, активируют, и платформа сама строит активы. После активации цены становятся историей актива, и исправить её обычными средствами почти невозможно.

1 ЗагрузитьAccount, Contract,Order в статусе Draft,OrderItem с ценами 2 Проверитьцены, даты, сроки,количества: доактивации, не после 3 Активироватьorder: обновитьстатус на Activated 4 Платформа строитAsset, AssetAction,AssetActionSource,AssetStatePeriod Не грузить напрямую историю актива: её создаёт только движокКаталог грузят по порядку: Product2, ProductSellingModel, ProductSellingModelOption, PricebookEntry.Ключи старой системы ставят на каждую загружаемую запись, чтобы потом сопоставить и обновить

Это упрощение. Полный порядок, исключения и что делать с открытыми сделками: kb/migration/case-legacy-cpq-to-revenue-cloud.md. Стратегии смены продуктовой модели: kb/migration/product-model-change-strategies.md.

5. Ловушки, на которых теряют больше всего времени

ЛовушкаКак проявляетсяПравило
Бизнес-определение, которого нет в данных«Переносим только активных клиентов», а поля «активный» нетКаждый критерий переводи в конкретное поле и условие, считай SOQL-запросом, подписывай у клиента
Похожие символы в значенияхСтадия с длинным тире вместо дефиса не попадает в фильтрВыгружай реальные уникальные значения, а не набирай их руками
Пустая дата окончания выглядит как живая подпискаМиллионы «вечных» строк попадают в scopeПустые значения проверяй отдельным запросом и решай явно
Значение по умолчанию в picklistПоле не загрузили, а у всех записей стоит одно значениеКаждое поле с default в mapping явно: грузим или оставляем
Системные поля нельзя загрузитьЗагрузка игнорирует или падает на поле, которое ставит платформаПроверь describe: createable и updateable до того, как обещать клиенту
Автоматизация срабатывает на каждую записьЗагрузка медленная, письма клиентам, ошибки лимитовBypass через настройку (custom permission или custom setting), а не выключение flows руками
Место в orgЗагрузка остановилась на середине: STORAGE_LIMIT_EXCEEDEDПроверь storage до загрузки и оцени объём
Устаревшая копия источникаЧисла в отчёте не сходятся с тем, что видит клиентСчитай по самому свежему источнику и пиши, откуда число

Полный список с примерами запросов: kb/migration/selection-criteria-lessons.md и kb/migration/data-migration-traps.md.

Итог одной фразой. Миграция это цикл «отобрать, перевести, почистить, загрузить, сверить, поправить правило» с ключами старой системы на каждой записи, загрузкой слоями от родителей к детям и журналом каждой странности; в Revenue Cloud сверх этого историю активов строит движок, поэтому проверяют до активации.
Дальше: Revenue Cloud. Назад: Интеграции.