Long-running DB migration progress
The scariest migrations are the ones where it’s unclear for a long time “is it done or another hour?”. An incremental ping every N% or every N minutes helps.
import os, time, requests
def push(t, m, p=4): requests.post(f"{os.environ['NOTIFLY_URL']}/message", params={"token": os.environ["NOTIFLY_TOKEN"]}, json={"title": t, "message": m, "priority": p}, timeout=5)
total = db.count("legacy_users")processed = 0last_push = time.time()last_pct = -1
for batch in db.iter_chunks("legacy_users", 10_000): migrate(batch) processed += len(batch) pct = int(processed / total * 100) if pct // 10 > last_pct // 10 or time.time() - last_push > 600: eta = (time.time() - t0) / max(processed, 1) * (total - processed) push(f"🗄️ Migration {pct}%", f"{processed:,} / {total:,}\nETA: {int(eta/60)} мин") last_push = time.time() last_pct = pct
push("🗄️ Migration: ✅ done", f"Обработано {processed:,} строк за {int((time.time()-t0)/60)} мин", 5)For migrations performed by an AI agent via apply — wrap them in the agent-run wrapper, and inside call the same push().
Related recipes
Section titled “Related recipes”- Finishing a long AI-agent task.
- Finishing long tasks — a general template.