""" Script one-off: rellena el campo 'leads' en MetricasDiarias para cada día de mayo ya registrado en GACampaignMes. Ejecutar una sola vez: python backfill_leads_mayo.py """ import json from datetime import datetime, timedelta from airtable_client import AirtableClient at = AirtableClient() now = datetime.now() print("Cargando registros GACampaignMes de mayo...") records = at.gacampaignmes.all( formula="AND({Mes}='5',{Año}='2026')", fields=["CampaignID", "MetricasDiarias", "Campaign Name (from CampaignID)"], ) # Mapping google_campaign_id → (gcm_record_id, metricas_dict) gid_to_gcm: dict[str, tuple[str, dict]] = {} campaigns_records = at.campaigns.all(fields=["CampaignID"]) at_id_to_gid = {r["id"]: str(r["fields"].get("CampaignID", "")).strip() for r in campaigns_records} for r in records: at_cids = r["fields"].get("CampaignID", []) if not at_cids: continue gid = at_id_to_gid.get(at_cids[0], "") if not gid: continue try: md = json.loads(r["fields"].get("MetricasDiarias") or "{}") except (json.JSONDecodeError, TypeError): md = {} gid_to_gcm[gid] = (r["id"], md) # Días de mayo que ya tienen métricas (sin 'leads') days_needed: set[str] = set() for _, (_, md) in gid_to_gcm.items(): for day_str, vals in md.items(): if "leads_lake" not in vals: days_needed.add(day_str) if not days_needed: print("Todos los días ya tienen 'leads_lake'. Nada que hacer.") exit(0) print(f"Días a rellenar: {sorted(days_needed)}") # Para cada día, obtener leads bulk for day_str in sorted(days_needed): try: day_int = int(day_str) date = datetime(now.year, 5, day_int) except ValueError: continue date_iso = date.strftime("%Y-%m-%d") print(f" > {date_iso} ...", end=" ", flush=True) leads_by_cid = at.get_leads_by_campaign_on_date(date_iso) updated = 0 for gid, (gcm_id, md) in gid_to_gcm.items(): if day_str in md and "leads_lake" not in md[day_str]: md[day_str]["leads_lake"] = leads_by_cid.get(gid, 0) updated += 1 print(f"{updated} campañas actualizadas") # Guardar en Airtable en lotes print("\nGuardando en Airtable...") batch = [ {"id": gcm_id, "fields": {"MetricasDiarias": json.dumps(md, ensure_ascii=False)}} for _, (gcm_id, md) in gid_to_gcm.items() if any("leads_lake" in v for v in md.values()) ] for i in range(0, len(batch), 10): at.gacampaignmes.batch_update(batch[i:i+10]) print(f"✓ Backfill completado: {len(batch)} registros actualizados.")