Files
Autoparts-DB/scripts/refresh_part_vehicle_preview.py
consultoria-as 042acd6207 OPCIÓN C + A1: Consolidación técnica + orjson
C1: Materialized view part_vehicle_preview (creación en progreso)
- Migración v3.3_materialized_view.sql
- catalog_service.py y dashboard/server.py ahora usan la MV
- Script refresh_part_vehicle_preview.py + warm_vehicle_cache.py actualizado

C2: Fix cache warming script (autónomo)
- Auto-re-ejecuta con sudo -u postgres si peer auth falla
- Args CLI: --dsn, --batch-size, --ttl, --dry-run

C3: CSS dinámico residual extraído
- sidebar.js → sidebar.css (nuevo)
- pos-utils.js → common.css (nuevo)
- Links agregados a 14 templates POS

C4: Script de load testing básico
- scripts/load_test.py: métricas p50/p95/p99, throughput, errores

C5: Documentación actualizada
- FASES_IMPLEMENTADAS.md: test count real, FASE 7 completa
- performance_audit_2026.md: anexo post-FASE 7, métricas actualizadas

A1: Serialización orjson
- pos/json_provider.py: DefaultJSONProvider con orjson.dumps/loads
- Aplicado a POS app y Dashboard server
- Fix indentation error en pos_bp.py

Tests: 73/73 pasando
2026-04-27 09:36:03 +00:00

83 lines
2.5 KiB
Python

#!/usr/bin/env python3
"""Refresh the part_vehicle_preview materialized view.
Uses REFRESH MATERIALIZED VIEW CONCURRENTLY so reads are not blocked.
Requires the unique index idx_pvp_part to exist.
Usage:
python3 refresh_part_vehicle_preview.py
python3 refresh_part_vehicle_preview.py --dsn "postgresql://..."
Recommended cron (as postgres user or via systemd timer):
0 3 * * * /usr/bin/python3 /home/Autopartes/scripts/refresh_part_vehicle_preview.py >> /var/log/nexus-pos/mv_refresh.log 2>&1
"""
import argparse
import os
import subprocess
import sys
import time
from datetime import datetime
import psycopg2
DEFAULT_DSN = os.environ.get('MASTER_DB_URL', 'postgresql://postgres@/nexus_autoparts')
def log(msg):
print(f"[{datetime.now().isoformat(timespec='seconds')}] {msg}", flush=True)
def _connect(dsn):
return psycopg2.connect(dsn)
def _ensure_connection(dsn):
try:
return _connect(dsn)
except psycopg2.OperationalError as exc:
err = str(exc).lower()
if 'peer' in err or 'authentication' in err:
if os.geteuid() == 0:
log("ERROR: PostgreSQL peer authentication failed.")
log(" Run as postgres OS user: sudo -u postgres python3 " + __file__)
sys.exit(1)
log("Peer auth failed. Re-running with sudo -u postgres ...")
cmd = ['sudo', '-u', 'postgres', sys.executable, __file__]
env = os.environ.copy()
env['MASTER_DB_URL'] = dsn
for i, arg in enumerate(sys.argv[1:], start=1):
if arg in ('--dsn', '-d') and i < len(sys.argv) - 1:
env['MASTER_DB_URL'] = sys.argv[i + 1]
ret = subprocess.call(cmd, env=env)
sys.exit(ret)
raise
def main():
parser = argparse.ArgumentParser(description='Refresh part_vehicle_preview MV')
parser.add_argument('--dsn', '-d', default=DEFAULT_DSN, help='PostgreSQL DSN')
args = parser.parse_args()
log("Starting REFRESH MATERIALIZED VIEW CONCURRENTLY part_vehicle_preview ...")
conn = _ensure_connection(args.dsn)
conn.autocommit = True
cur = conn.cursor()
start = time.time()
try:
cur.execute("SET statement_timeout = 0;")
cur.execute("REFRESH MATERIALIZED VIEW CONCURRENTLY part_vehicle_preview;")
elapsed = time.time() - start
log(f"Refresh completed in {elapsed:.1f}s")
except psycopg2.Error as exc:
log(f"ERROR: {exc}")
sys.exit(1)
finally:
cur.close()
conn.close()
if __name__ == '__main__':
main()