- MetricasDiarias now stores both: leads (Google conv) and leads_lake (Airtable count) - Update backfill and migration scripts accordingly - migrate_leads_field.py executed: 49 May records updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
80 lines
2.5 KiB
Python
80 lines
2.5 KiB
Python
"""
|
|
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.")
|