В выгрузке CRM повторяются строки: что происходит, пока список меняется

В CRM десять тысяч записей. Экспорт читает их по тысяче, а сотрудники продолжают добавлять новые. Файл успешно сформирован, но один клиент встречается дважды, другого нет. Ошибка может существовать даже при правильной работе каждой отдельной страницы: между запросами изменился сам упорядоченный список.
Смещение относится к текущему набору
При подходе OFFSET следующий запрос пропускает определённое число строк в текущем результате. Если перед уже прочитанной частью появилась новая запись, позиции сдвинулись. Пропустить прежнее количество строк — не то же самое, что продолжить после последнего уже выданного объекта.
Удаление или изменение сортировочного поля создаёт другие варианты пропусков и повторов. Без определённого порядка запрос вообще не обещает стабильную последовательность. Для сортировки с одинаковыми значениями нужен устойчивый дополнительный ключ, иначе граница страницы остаётся неоднозначной.
| Этап | Список | Полученный результат |
|---|---|---|
| Первая страница | 1, 2, 3, 4, 5, 6 | 1, 2, 3 |
| Добавили запись перед списком | 0, 1, 2, 3, 4, 5, 6 | Позиции изменились |
| Вторая страница со смещением 3 | Текущий список | 3, 4, 5 — повтор 3 |
| Продолжение по ключу после 3 | Текущий список | 4, 5, 6 |
Курсор должен соответствовать сортировке
Продолжение по устойчивому ключу говорит: читать после последнего подтверждённого значения. Если порядок задаётся парой «время создания, ID», курсор должен учитывать оба, а не только время. Обновляемое поле вроде имени клиента плохо подходит для простого стабильного прохода, если его изменение не предусмотрено моделью.
Для внешнего API используйте документированный механизм продолжения. Не считайте произвольный параметр page_token аналогом собственных предположений. Провайдер может ограничивать срок жизни курсора, менять набор данных или требовать те же фильтры во всех запросах.
Курсор не является снимком данных
Переход после ключа помогает против определённых сдвигов, но не замораживает содержание. Новые записи с большими ключами могут попасть в дальнейшую выгрузку, а изменение уже прочитанной строки останется незамеченным. Если нужен отчёт на единый момент, требуется отдельное решение согласованности.
Возможны снимок в источнике, согласованный серверный экспорт или другой поддерживаемый механизм. Одна верхняя граница ID ограничивает часть новых объектов, но не фиксирует изменения полей старых. Длинная транзакция тоже имеет стоимость для работающей базы, поэтому её нельзя вводить без оценки нагрузки и жизненного цикла.
Успех задания и полнота файла — разные проверки
Сохраняйте параметры экспорта, источник, границы набора, версию схемы и контрольные количества. Для повторного запуска определите, продолжать прежний снимок или начинать новый. Иначе две половины файла могут относиться к разным состояниям системы.
Если экспорт содержит закрытые данные, файл должен иметь ограниченный доступ и понятный срок хранения. Очередь задач и временная ссылка решают свои задачи, но не исправляют пропуски в наборе. Технический статус «готово» не должен скрывать отсутствие контрольной сверки.
Что показывает симулятор
Введите уникальные целые ID исходного списка, размер страницы и новые ID, появившиеся после первой страницы. Инструмент сравнит вторую страницу по смещению и продолжение по последнему ключу. Он не моделирует все виды изменений, сложную сортировку или изоляцию настоящей базы.
Дополнительно показывается, какие исходные ID не вошли в две прочитанные страницы. Это не всегда ошибка: если исходный список длиннее двух страниц, остаток ещё просто не прочитан. Пример нужен для демонстрации сдвига границы, а не для вывода, что два запроса обязаны выгрузить произвольную базу целиком.
Задание разработчику без расплывчатого «починить Excel»
Передайте воспроизводимый маленький набор, изменение между страницами и ожидаемую политику состава файла. Укажите, допускаются ли новые записи во время выгрузки и на какой момент нужны значения. Затем проверьте ID и содержимое, а не только число строк.
После исправления полезно оставить такой сценарий в проверках обмена. Переход на более удобную библиотеку выгрузки сам по себе не решит проблему: согласованность начинается в способе чтения данных, ещё до форматирования таблицы.
Сдвиг второй страницы при добавлении записей
Только числовой неизменяемый ключ и вставки между двумя чтениями. Курсор здесь не объявляется снимком всей базы. Расчёт выполняется на вашем устройстве, введённые данные никуда не отправляются.
Материалы для проверки
Если нужна реализация
Состав работ зависит от текущего проекта и подтверждённой причины. Можно обсудить диагностику или разработку подходящего решения.
