Merge pull request 'Enhance database URL validation in Alembic environment' (#252) from ci-cd/migrations into development

Reviewed-on: ADUANASOFT/anexo76#252
This commit is contained in:
2026-03-24 20:40:19 +00:00

View File

@@ -3,13 +3,14 @@ import logging
import os
import sys
from logging.config import fileConfig
from urllib.parse import quote_plus, urlparse
from urllib.parse import quote_plus
from alembic import context
from alembic.operations import ops
from core.config import settings
from core.database import Base
from sqlalchemy import engine_from_config, pool
from sqlalchemy.engine.url import make_url
logger = logging.getLogger(__name__)
@@ -38,19 +39,27 @@ def _normalize_alembic_sqlalchemy_url(url: str) -> str:
return url
def _validate_sqlalchemy_url(url: str, env_key: str) -> None:
"""Misma validación que create_engine; evita urlparse (falla con esquemas tipo postgresql+psycopg2)."""
try:
make_url(url)
except Exception as e:
raise RuntimeError(
f"{env_key} no es una URL de SQLAlchemy válida. "
"Ejemplo: postgresql://usuario:clave@host:5432/nombre_bd"
) from e
def get_database_url():
"""Obtiene la URL de la base de datos (PostgreSQL) desde variables de entorno o alembic.ini."""
# CI / pytest: misma URL que los tests (secret TEST_DATABASE_URL) o DATABASE_URL explícita.
# Nota: ("X") sin coma es str, no tupla; el for iteraría caracteres y jamás leería la variable.
for env_key in ("TEST_DATABASE_URL"):
# CRÍTICO: debe ser tupla con coma final si un solo elemento: ("X",) — si no, ("X") es str y el for
# itera caracteres; env_key "_" + os.environ["_"] (común en shells) rompe con URL inválida.
for env_key in ("TEST_DATABASE_URL", "DATABASE_URL"):
raw = os.environ.get(env_key)
if raw and raw.strip():
normalized = _normalize_alembic_sqlalchemy_url(raw)
if not urlparse(normalized).scheme:
raise RuntimeError(
f"{env_key} no es una URL válida (falta esquema). "
"Ejemplo: postgresql://usuario:clave@host:5432/nombre_bd"
)
_validate_sqlalchemy_url(normalized, env_key)
return normalized
# Construcción desde settings (CORE_DB_* en .env / entorno)