Modelo de datos SQLite
La salida persistente de camara-senadores-mex es senado.db, una base SQLite local diseñada para preservar evidencia de extracción sin completar huecos históricos. El contrato documentado distingue votaciones, votos nominales y perfiles senatoriales disponibles.
Configuración de conexión
La capa de persistencia abre SQLite con configuración defensiva:
PRAGMA journal_mode=WAL;
PRAGMA busy_timeout=5000;
PRAGMA foreign_keys=ON;
En Python, get_connection activa WAL, busy_timeout=5000, foreign_keys=ON y row_factory = sqlite3.Row para crawler/helpers. El validador abre la base en modo solo lectura con sqlite3.connect(uri, uri=True) y también define row_factory; no se asume que esa conexión read-only reactive PRAGMAs de escritura o concurrencia.
Esquema lógico
CREATE TABLE votaciones (
id INTEGER PRIMARY KEY,
legislature INTEGER NOT NULL,
year INTEGER NOT NULL,
period INTEGER NOT NULL,
date TEXT NOT NULL,
url TEXT NOT NULL,
scraped_at TEXT DEFAULT (datetime('now'))
);
CREATE TABLE senadores (
id INTEGER PRIMARY KEY,
nombre TEXT NOT NULL,
sexo TEXT,
tipo_eleccion TEXT,
estado TEXT,
url TEXT NOT NULL,
scraped_at TEXT DEFAULT (datetime('now'))
);
CREATE TABLE votos_nominales (
id INTEGER PRIMARY KEY AUTOINCREMENT,
votacion_id INTEGER NOT NULL,
senador_id INTEGER NOT NULL,
nombre TEXT NOT NULL,
partido TEXT NOT NULL,
voto TEXT NOT NULL,
FOREIGN KEY (votacion_id) REFERENCES votaciones(id),
UNIQUE(votacion_id, senador_id)
);
CREATE INDEX idx_votos_votacion_id ON votos_nominales(votacion_id);
CREATE INDEX idx_votos_senador_id ON votos_nominales(senador_id);
El esquema operativo se entiende por estas garantías:
votaciones.idysenadores.idson claves primarias institucionales.votos_nominales.ides autoincremental yUNIQUE(votacion_id, senador_id)evita duplicados por votación.votos_nominales.votacion_idreferenciavotaciones(id);senador_idse conserva como identificador institucional, pero no hay FK declarada haciasenadores(id).urles obligatoria envotacionesysenadores, pero el esquema no declara unicidad sobre esa columna.
Persistencia
La escritura es idempotente:
INSERT OR REPLACEactualiza votaciones y perfiles cuando la fuente vuelve a entregar el mismo ID.INSERT OR IGNOREevita duplicar votos nominales ya persistidos por la restricciónUNIQUE(votacion_id, senador_id).
Este diseño permite reintentos parciales sin borrar evidencia previa. Los campos vacíos no se normalizan artificialmente: se conservan porque también son señal de calidad de fuente o parsing.
Contrato Sen./Dip.
El README y el validador documentan que el dataset esperado es senatorial. Aun así, esta página no afirma un filtro explícito del parser por la primera columna Sen./Dip.: el contrato debe leerse como alcance documentado y auditado, no como garantía adicional no verificada aquí.