Enhance database URL validation in Alembic environment

- Introduced a new validation function for SQLAlchemy URLs to ensure proper formatting and provide clearer error messages.
- Updated the `get_database_url` function to include checks for both `TEST_DATABASE_URL` and `DATABASE_URL`, improving flexibility in configuration.
- Removed the previous URL scheme validation in favor of the new validation method, streamlining the error handling process.

These changes aim to improve the robustness and clarity of database connection handling in the application.
This commit is contained in:
2026-03-24 15:39:53 -05:00
parent 18e4477bf1
commit 2cd6b165d7

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)