🇬🇧 English · 🇪🇸 Español
Base de datos de caché
Disponible a partir de puremacro 0.66.0. Reemplaza la caché de archivos planos
~/.cache/puremacro/http/*.bin + *.jsonde las versiones 0.65.0 e inferiores.
Ubicación
Archivo SQLite único en ~/.cache/puremacro/cache.db (modificable mediante
$PUREMACRO_HTTP_CACHE_DIR). Si la variable de entorno termina en .db, se
utiliza esa ruta de forma literal; en caso contrario se interpreta como
directorio y la base de datos queda en <dir>/cache.db.
Esquema
CREATE TABLE http_cache (
key TEXT PRIMARY KEY, -- sha256(url) hex
url TEXT NOT NULL,
fetched_at INTEGER NOT NULL, -- unix epoch seconds
content_type TEXT,
body BLOB NOT NULL
);
CREATE TABLE alfred_vintages (
series_id TEXT NOT NULL,
observation_date TEXT NOT NULL, -- ISO YYYY-MM-DD
vintage_date TEXT NOT NULL, -- ISO YYYY-MM-DD
value REAL,
PRIMARY KEY (series_id, observation_date, vintage_date)
);
CREATE TABLE connector_events (
ts INTEGER NOT NULL, -- unix epoch seconds
source TEXT NOT NULL, -- connector name
outcome TEXT NOT NULL,
fallback_used TEXT NOT NULL
);
CREATE TABLE realtime_vintages (
provider TEXT NOT NULL, -- 'banxico' / 'inegi' / 'bcb' / 'bcch'
country TEXT NOT NULL, -- ISO-3, upper case
series_id TEXT NOT NULL, -- the provider's own identifier
observation_date TEXT NOT NULL, -- ISO YYYY-MM-DD, the reference period
vintage_date TEXT NOT NULL, -- ISO YYYY-MM-DD, the SNAPSHOT date
value REAL,
PRIMARY KEY (provider, country, series_id, observation_date, vintage_date)
);
CREATE TABLE schema_version (
component TEXT PRIMARY KEY,
version INTEGER NOT NULL
);
El modo de diario WAL (PRAGMA journal_mode=WAL) está habilitado para que
varios cuadernos que accedan a la misma base de datos no se bloqueen
mutuamente en las operaciones de escritura.
La inicialización del esquema es aditiva (CREATE TABLE IF NOT EXISTS +
INSERT OR IGNORE), de modo que un archivo de caché escrito por una versión
anterior incorpora las tablas nuevas al abrirse por primera vez y conserva sus
filas. La tabla schema_version se inicializa con una fila por tabla
(http_cache, alfred_vintages, connector_events, realtime_vintages,
todas en la versión 1).
Instantáneas de tiempo real (realtime_vintages)
Incorporada en puremacro 3.4.0.
Banxico, INEGI, BCB y BCCh publican únicamente la edición vigente en el momento
de la consulta — sobrescriben en el sitio y no incluyen campo de añada —, de
manera que el único historial de revisiones disponible para ellos es el que
esta tabla acumula localmente. Cada descarga se almacena con la marca de su
fecha de instantánea, y una llamada posterior devuelve cada instantánea
almacenada como una añada. Dos capturas del mismo día son, por tanto, una sola
añada y no dos: la clave primaria termina en vintage_date y la escritura es
INSERT OR REPLACE, de modo que una nueva descarga el mismo día sobrescribe en
lugar de duplicar.
import pandas as pd
import puremacro._cache_db as db
snap = pd.DataFrame({
"provider": ["bcb"] * 3,
"country": ["BRA"] * 3,
"series_id": ["432"] * 3,
"date": pd.to_datetime(["2026-01-01", "2026-02-01", "2026-03-01"]),
"vintage": pd.to_datetime(["2026-03-15"] * 3),
"value": [11.25, 11.25, 11.00],
})
db.store_realtime_vintages(snap) # -> 3 rows written
db.query_realtime_vintages("bcb", "BRA", "432") # every stored snapshot
db.query_realtime_vintages("bcb", "BRA", "432", # as-of cutoff:
vintage_date="2026-03-01") # keeps vintage_date <= cutoff
db.record_connector_event("bcb", "success", "none") # fetch telemetry
store_realtime_vintages(df)admite los nombres de columnadate/vintageo bienobservation_date/vintage_date, convierte el país a mayúsculas, normaliza ambas fechas y el valor, descarta las filas que no puede interpretar y devuelve el número de filas escritas. La ausencia de una columna obligatoria lanzaValueError.query_realtime_vintages(provider, country, series_id, *, vintage_date=None)devuelve[date, vintage, value, provider, country, series_id]ordenado por(observation_date, vintage_date), o un marco vacío con esas columnas. El argumentovintage_datees un corte «a fecha de», no una coincidencia exacta: conserva las instantáneas tomadas en esa fecha o antes, que es lo que reconstruye el conjunto de información disponible para un responsable de política económica.record_connector_event(source, outcome, fallback_used)escribe una fila de telemetría de descarga; véasedocs/es/CONNECTOR_HEALTH.md.
El almacenamiento es una comodidad, nunca el objetivo: una instantánea que no
puede escribirse se devuelve igualmente al invocador con un UserWarning, y una
caché que no puede leerse se reporta y se trata como vacía.
Migración desde 0.65.0
El módulo de caché HTTP ejecuta la migración de forma diferida en la primera
operación de lectura o escritura tras la actualización: si existen archivos
cache_dir/*.bin y la tabla http_cache está vacía, las entradas se insertan
en la base de datos (sin eliminar los originales) y un UserWarning remite a
la herramienta de línea de comandos:
python tools/cache_migrate.py # dry-run; report count
python tools/cache_migrate.py --apply # migrate
python tools/cache_migrate.py --apply --rm # migrate + delete originals
La migración es idempotente: volver a ejecutarla no tiene ningún efecto.
Introspección
import puremacro.cache as C
import pandas as pd
C.http_list_urls() # sorted list of cached URLs
C.http_cache_size_bytes() # total body bytes
C.http_cache_clear() # clear ALL entries; returns count
C.http_cache_clear(older_than=pd.Timedelta(days=30)) # clear stale only
Las eliminaciones masivas (más de 1000 filas) emiten automáticamente un
VACUUM para que el archivo en disco se reduzca de tamaño efectivamente.
Semántica de fallos
cache_read / cache_write no deben nunca propagar excepciones al
invocador (este es un contrato esencial desde la versión 0.65.0). Los fallos
en la base de datos emiten un UserWarning y degradan el comportamiento de
forma controlada: cache_read devuelve None y cache_write no ejecuta
ninguna acción. Un cuaderno de investigación que consolide 30 fuentes
simplemente operará más lento (sin caché); nunca se interrumpirá con un error.
Pyodide
sqlite3 es parte de la biblioteca estándar de Python y está disponible en
todos los entornos de ejecución admitidos, incluido Pyodide. El archivo de
caché reside en el sistema de archivos virtual de Pyodide; para persistir la
caché entre recargas de página, el usuario debe montar IDBFS o un mecanismo
equivalente.