{"@context":"https://schema.org","@graph":[{"@type":"WebPage","@id":"https://inquir.org/ru/use-cases/scheduled-data-sync#webpage","url":"https://inquir.org/ru/use-cases/scheduled-data-sync","name":"Синхронизация данных по расписанию: инкрементальный режим с курсором последней синхронизации","headline":"Синхронизация данных по расписанию: инкрементальный режим с курсором последней синхронизации","description":"Serverless scheduled data sync: инкрементальная синхронизация с cron-триггерами, курсорами watermark, идемпотентными upsert и историей — без crontab на VPS, без тихих сбоев.","inLanguage":"ru-RU","isPartOf":{"@id":"https://inquir.org/#website"},"author":{"@type":"Organization","name":"Inquir"},"datePublished":"2025-01-01T00:00:00.000Z","dateModified":"2026-04-20T00:00:00.000Z","citation":"https://inquir.org/docs"},{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Главная","item":"https://inquir.org"},{"@type":"ListItem","position":2,"name":"Сценарии","item":"https://inquir.org/use-cases"},{"@type":"ListItem","position":3,"name":"Синхронизация данных по расписанию","item":"https://inquir.org/use-cases/scheduled-data-sync"}]},{"@type":"HowTo","@id":"https://inquir.org/ru/use-cases/scheduled-data-sync#howto","name":"Синхронизация данных по расписанию: инкрементальный режим с курсором последней синхронизации","description":"Serverless scheduled data sync: инкрементальная синхронизация с cron-триггерами, курсорами watermark, идемпотентными upsert и историей — без crontab на VPS, без тихих сбоев.","inLanguage":"ru-RU","author":{"@type":"Organization","name":"Inquir"},"step":[{"@type":"HowToStep","position":1,"name":"Прочитать курсор","text":"Запросить `last_synced_at` из базы или persistent storage в начале каждого прогона."},{"@type":"HowToStep","position":2,"name":"Запросить дельту","text":"`WHERE updated_at > last_synced_at ORDER BY updated_at LIMIT N` — инкрементальный запрос."},{"@type":"HowToStep","position":3,"name":"Upsert и сдвиг курсора","text":"Сделать upsert батча, затем обновить `last_synced_at = MAX(updated_at)` в одной транзакции."}],"isPartOf":{"@id":"https://inquir.org/ru/use-cases/scheduled-data-sync#webpage"}},{"@type":"FAQPage","@id":"https://inquir.org/ru/use-cases/scheduled-data-sync#faq","url":"https://inquir.org/ru/use-cases/scheduled-data-sync","isPartOf":{"@id":"https://inquir.org/ru/use-cases/scheduled-data-sync#webpage"},"mainEntity":[{"@type":"Question","name":"Что если прогон упал на середине?","acceptedAnswer":{"@type":"Answer","text":"Следующий запуск по расписанию снова прочитает прежнюю отметку `last_synced_at`: те же строки запросятся повторно. При идемпотентном UPSERT дубликаты не появятся."}},{"@type":"Question","name":"Где хранить состояние курсора?","acceptedAnswer":{"@type":"Answer","text":"Обычно отдельная таблица `sync_state` или key-value с одной записью на каждый источник и тип синхронизации."}}]}]}