data - PowerSystem2024/CapybaraFilms_ProyectoTercerSemestre GitHub Wiki
Este documento detalla la infraestructura de conectividad a la base de datos proporcionada por la clase DatabaseConnection
. Esta clase actúa como el componente central para la integración con PostgreSQL en el sistema Capybara Films, manejando la gestión de conexiones, el procesamiento de transacciones, la ejecución de consultas y la recuperación de errores para todas las operaciones de base de datos a lo largo de la aplicación.
- 1. Configuración de la Conexión
- 2. Arquitectura de la Clase DatabaseConnection
- 3. Gestión del Ciclo de Vida de la Conexión
- 4. Manejo de Transacciones
- 5. Interfaz de Ejecución de Consultas
- 6. Ejemplos de Uso de DatabaseConnection en los DAOs
- 7. Manejo de Errores y Recuperación
- 8. Integración con la Arquitectura del Sistema
La clase DatabaseConnection
está configurada para conectarse a una base de datos PostgreSQL alojada en Railway. Los parámetros de conexión están codificados en el constructor e incluyen el nombre de la base de datos, las credenciales de usuario, el host y la información del puerto.
Parámetro | Valor Predeterminado | Propósito |
---|---|---|
database |
railway | Nombre de la base de datos objetivo |
user |
postgres | Cuenta de usuario de la base de datos |
password |
[hardcoded] | Credencial de autenticación |
host |
turntable.proxy.rlwy.net | Nombre de host del proxy de Railway |
port |
44390 | Puerto del proxy de Railway |
La configuración de la conexión se almacena en una estructura de diccionario en CapybaraFilms/data/DatabaseConnection
y se utiliza a lo largo del ciclo de vida de la conexión.
El método _conectar()
utiliza el operador de desempaquetado **
para pasar los parámetros de configuración a psycopg2.connect()
.
¿Por qué se usa **self.config
?
- Flexibilidad: Permite pasar todos los parámetros del diccionario como argumentos nombrados
-
Mantenibilidad: Si se agregan nuevos parámetros al diccionario, no es necesario modificar la llamada a
connect()
- Legibilidad: Evita tener que especificar cada parámetro individualmente en la llamada
Esto es equivalente a escribir:
psycopg2.connect(
database=self.config["database"],
user=self.config["user"],
password=self.config["password"],
host=self.config["host"],
port=self.config["port"]
)
La clase DatabaseConnection
encapsula la lógica de conexión y las operaciones básicas con la base de datos, utilizando la biblioteca psycopg2
para la interacción con PostgreSQL.
classDiagram
class DatabaseConnection {
-connection: psycopg2.connection
-cursor: psycopg2.cursor
-config: dict
+init(database, user, password, host, port)
-_conectar() : void
-_validar_conexion_activa() : void
+manejar_cursor() : contextmanager
+ejecutar_consulta(consulta, valores) : void
+obtener_datos(consulta, valores) : list
+cerrar_conexion() : void
}
class psycopg2 {
+OperationalError
+DatabaseError
+connect()
}
DatabaseConnection "usa" --> psycopg2
-
connection
: Objeto de conexión con la base de datos (psycopg2.connection
). -
cursor
: Objeto cursor para ejecutar consultas (psycopg2.cursor
). -
config
: Diccionario que almacena los parámetros de configuración de la conexión.
-
__init__(self, database, user, password, host, port)
: Constructor de la clase, inicializa la configuración de la conexión. -
_conectar(self)
: Método privado para establecer la conexión inicial con la base de datos y obtener un cursor. -
_validar_conexion_activa(self)
: Método privado para verificar la salud de la conexión y reconectar si es necesario. -
manejar_cursor(self)
: Gestor de contexto (contextmanager
) para operaciones transaccionales y gestión automática del cursor. -
ejecutar_consulta(self, consulta, valores)
: Ejecuta consultas SQL que no devuelven resultados (INSERT, UPDATE, DELETE). -
obtener_datos(self, consulta, valores)
: Ejecuta consultas SQL que devuelven resultados (SELECT). -
cerrar_conexion(self)
: Cierra de forma segura la conexión y el cursor de la base de datos.
Esta sección abarca el manejo completo de la conexión a la base de datos, desde el establecimiento inicial hasta la limpieza final de recursos, proporcionando una visión integral del ciclo de vida de la conexión en el sistema Capybara Films.
La clase DatabaseConnection
se inicializa automáticamente con los parámetros de conexión a PostgreSQL alojado en Railway. La configuración se almacena en un diccionario que incluye todos los parámetros necesarios para la conexión.
El proceso de conexión se ejecuta automáticamente durante la inicialización de la clase: DatabaseConnection.py:25-26
El sistema implementa un mecanismo robusto de validación de conexión que verifica automáticamente el estado de la conexión antes de cada operación: DatabaseConnection.py:40-46
- Detección automática de conexiones cerradas
- Reconexión transparente sin intervención del usuario
- Recreación del cursor cuando es necesario
- Logging informativo del proceso de reconexión
La gestión de cursores se realiza a través del gestor de contexto manejar_cursor()
, que proporciona manejo automático de transacciones y limpieza de recursos: DatabaseConnection.py:48-60
- Validación automática de conexión antes de cada operación
- Commit automático en operaciones exitosas
- Rollback automático en caso de excepciones
- Recreación del cursor después de cada operación
DatabaseConnection.py:59-60
Una característica importante del gestor de contexto es que el cursor se recrea automáticamente después de cada operación. Esto asegura que cada operación de base de datos tenga un cursor limpio y evita problemas de estado entre transacciones consecutivas.
Beneficios de la recreación automática:
- Previene conflictos de estado entre operaciones
- Garantiza que cada transacción tenga un cursor fresco
- Mejora la robustez del sistema ante errores de cursor
El método cerrar_conexion()
proporciona una limpieza segura y completa de todos los recursos de base de datos:
- Cierre seguro del cursor con manejo de excepciones.
- Cierre de la conexión principal.
- Logging de confirmación de cierre exitoso.
- Manejo de errores durante el proceso de limpieza.
La clase DatabaseConnection se integra con toda la arquitectura del sistema a través del patrón de inyección de dependencias. Una sola instancia de conexión es compartida entre todos los DAOs del sistema: main.py:20-26
- Cada DAO recibe una instancia de
DatabaseConnection
en su constructor - Los DAOs utilizan los métodos
ejecutar_consulta()
yobtener_datos()
para interactuar con la base de datos - El manejo de transacciones y conexiones es transparente para los DAOs
Esta arquitectura de gestión del ciclo de vida proporciona:
- Resiliencia: Reconexión automática ante fallos de conexión
- Consistencia: Manejo transaccional automático con commit/rollback
- Eficiencia: Reutilización de conexiones y cursores
- Simplicidad: Interfaz transparente para los DAOs
- Robustez: Manejo integral de errores y limpieza de recursos
El diseño asegura que todas las operaciones de base de datos en el sistema Capybara Films sean confiables, eficientes y mantengan la integridad de los datos a través de un manejo automático y transparente del ciclo de vida de la conexión.
La gestión de transacciones se implementa a través del gestor de contexto manejar_cursor()
, que proporciona funcionalidad de commit
/rollback
automático. Esto asegura la consistencia de los datos en todas las operaciones de la base de datos.
graph TD
Inicio[Inicio de Transacción] --> Validar[validar_conexion_activa]
Validar --> Cursor[cursor = connection.cursor]
Cursor --> Yield[yield cursor]
Yield --> Ejecutar[Ejecutar SQL]
Ejecutar -- "Excepción?" --> ExceptionCheck{Excepción?}
ExceptionCheck -- "Sí" --> Rollback[connection.rollback]
ExceptionCheck -- "No" --> Commit[connection.commit]
Rollback --> Raise[raise exception]
Raise --> CerrarCursor[cursor.close]
Commit --> CerrarCursor
CerrarCursor --> Fin[Fin de Transacción]
El gestor de contexto CapybaraFilms/data/DatabaseConnection.py:48-60
maneja el ciclo de vida completo de la transacción, incluyendo el rollback automático en caso de excepciones y la gestión del cursor para operaciones subsiguientes.
La clase DatabaseConnection proporciona dos métodos principales para las operaciones de base de datos:
-
Propósito: Se utiliza para operaciones
INSERT
,UPDATE
,DELETE
y otras operaciones que no devuelven resultados. -
Comportamiento: Este método maneja automáticamente la gestión de transacciones y el registro de errores.
# Firma del método desde DatabaseConnection.py:62-75
def ejecutar_consulta(self, consulta, valores=None)
Fuente: DatabaseConnection.py:62-75
-
Propósito: Se utiliza para consultas SELECT que devuelven conjuntos de resultados.
-
Comportamiento: Este método devuelve una lista de tuplas que representan los resultados de la consulta.
# Firma del método desde DatabaseConnection.py:77-91
def obtener_datos(self, consulta, valores=None)
Fuente: DatabaseConnection.py:77-91
Ambos métodos utilizan consultas parametrizadas para prevenir la inyección de SQL y aprovechan el gestor de contexto manejar_cursor()
para garantizar la seguridad transaccional.
Aquí tienes ejemplos prácticos de cómo los diferentes DAOs utilizan DatabaseConnection
en el sistema Capybara Films:
# Ejemplo de uso en ClienteDAO - Búsqueda por DNI
def buscar_por_dni(self, dni: str):
try:
sentencia = "SELECT id_cliente, dni, nombre, apellido, email FROM cliente WHERE dni = %s"
resultado = self.db.obtener_datos(sentencia, (dni,))
if resultado:
fila = resultado[0]
return Cliente(fila[0], fila[1], fila[2], fila[3], fila[4])
return None
Fuente: ClienteDAO.py:42-48
# Ejemplo de uso en ClienteDAO - Inserción de datos
sentencia = """
INSERT INTO cliente (dni, nombre, apellido, email)
VALUES (%s, %s, %s, %s)
RETURNING id_cliente
"""
valores = (cliente.dni, cliente.nombre, cliente.apellido, cliente.email)
self.db.ejecutar_consulta(sentencia, valores)
Fuente: ClienteDAO.py:26-32
# Ejemplo de uso en ButacaDAO - Consulta con parámetros
def butacas_por_sala(self, id_sala: int):
try:
sentencia = "SELECT id_butaca, fila, columna, categoria, estado FROM butaca WHERE id_sala = %s"
resultado = self.db.obtener_datos(sentencia, (id_sala,))
return [Butaca(fila[0], fila[1], fila[2], fila[3], fila[4]) for fila in resultado]
Fuente: ButacaDAO.py:72-75
# Ejemplo de uso en ButacaDAO - Actualización de datos
def actualizar_estado(self, id_butaca: int, estado: bool):
try:
sentencia = "UPDATE butaca SET estado = %s WHERE id_butaca = %s"
self.db.ejecutar_consulta(sentencia, (estado, id_butaca))
Fuente: ButacaDAO.py:58-62
# Ejemplo de uso en ReservaDAO - Inserción con RETURNING
sentencia = """
INSERT INTO reserva (id_cliente, id_sala, fecha_hora)
VALUES (%s, %s, NOW())
RETURNING id_reserva
"""
valores = (id_cliente, id_sala)
resultado = self.db.obtener_datos(sentencia, valores)
Fuente: ReservaDAO.py:40-47
# Ejemplo de uso en SalaDAO - Consulta con filtro
def buscar_por_pelicula(self, id_pelicula: int):
try:
sentencia = "SELECT id_sala, id_pelicula FROM sala WHERE id_pelicula = %s"
resultado = self.db.obtener_datos(sentencia, (id_pelicula,))
Fuente: SalaDAO.py:82-84
-
Consultas Parametrizadas: Todos los DAOs utilizan parámetros (%s) para prevenir inyección SQL.
-
Manejo de Excepciones: Cada DAO implementa bloques
try-except
para capturar errores de base de datos. -
Construcción de Entidades: Los resultados se convierten automáticamente en objetos de dominio usando desempaquetado de tuplas.
-
Dos Métodos Principales:
-
obtener_datos()
: Para consultasSELECT
que devuelven resultados -
ejecutar_consulta()
: Para operacionesINSERT
,UPDATE
,DELETE
Estos ejemplos demuestran cómo DatabaseConnection
proporciona una interfaz consistente y segura para todas las operaciones de base de datos en el sistema.
El sistema implementa un manejo de errores integral para las operaciones de base de datos, con manejo específico para diferentes tipos de excepciones de base de datos:
Tipo de Excepción | Estrategia de Manejo | Ubicación del Código |
---|---|---|
OperationalError |
Registrar error, intentar reconexión |
DatabaseConnection.py:34-38 DatabaseConnection.py:70-71
|
DatabaseError |
Registrar error, hacer rollback de la transacción | DatabaseConnection.py:72-73 |
Generic Exception |
Registrar error, volver a lanzar para que el llamador lo maneje |
DatabaseConnection.py:74-75 DatabaseConnection.py:89-91
|
El manejo de errores asegura que:
-
Las fallas de conexión activan intentos automáticos de reconexión.
-
Los errores de la base de datos resultan en un rollback de la transacción.
-
Todos los errores se registran con mensajes descriptivos.
-
Las excepciones se propagan correctamente al código que las invocó.
La clase DatabaseConnection
actúa como el componente central de infraestructura en la arquitectura del sistema Capybara Films, proporcionando conectividad unificada a la base de datos para toda la capa de acceso a datos.
El sistema implementa un patrón de inyección de dependencias donde una sola instancia de DatabaseConnection
es compartida entre todos los DAOs del sistema:
# Inicialización centralizada en main.py [header-3](#header-3)
db_connection = DatabaseConnection()
cliente_dao = ClienteDAO(db_connection)
pelicula_dao = PeliculaDAO(db_connection)
sala_dao = SalaDAO(db_connection)
butaca_dao = ButacaDAO(db_connection)
reserva_dao = ReservaDAO(db_connection)
candy_dao = CandyDAO(db_connection)
-
Centralización de Recursos: Una sola conexión compartida optimiza el uso de recursos de base de datos y simplifica la gestión de conexiones.
-
Consistencia Transaccional: Todos los DAOs utilizan la misma infraestructura de transacciones, garantizando comportamiento uniforme.
-
Mantenibilidad: Los cambios en la lógica de conexión se centralizan en una sola clase, facilitando el mantenimiento.
-
Escalabilidad: El diseño permite futuras optimizaciones como pooling de conexiones sin afectar los DAOs existentes.
Esta integración asegura que DatabaseConnection
sirva como la base sólida sobre la cual se construye toda la funcionalidad de persistencia del sistema de gestión de cine.