Initial commit: SYNC_API project
This commit is contained in:
1
sync_api/database/__init__.py
Normal file
1
sync_api/database/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# Database module initialization
|
||||
BIN
sync_api/database/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
sync_api/database/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
sync_api/database/__pycache__/connection.cpython-312.pyc
Normal file
BIN
sync_api/database/__pycache__/connection.cpython-312.pyc
Normal file
Binary file not shown.
132
sync_api/database/connection.py
Normal file
132
sync_api/database/connection.py
Normal file
@@ -0,0 +1,132 @@
|
||||
import pyodbc
|
||||
import logging
|
||||
from typing import Optional, Dict, Any, List
|
||||
from contextlib import contextmanager
|
||||
from config.settings import settings
|
||||
import time
|
||||
|
||||
|
||||
class SQLServerConnection:
|
||||
def __init__(self):
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
def _build_connection_string(self, server_type="main") -> str:
|
||||
"""Construye la cadena de conexión para SQL Server"""
|
||||
if server_type == "backup":
|
||||
return (
|
||||
f"DRIVER={{{settings.backup_driver}}};"
|
||||
f"SERVER={settings.backup_server},{settings.backup_port};"
|
||||
f"DATABASE={settings.backup_database};"
|
||||
f"UID={settings.backup_user};"
|
||||
f"PWD={settings.backup_password};"
|
||||
f"TrustServerCertificate=yes;"
|
||||
f"Connection Timeout=30;"
|
||||
)
|
||||
else: # main server (CONTROLDESK)
|
||||
return (
|
||||
f"DRIVER={{{settings.database_driver}}};"
|
||||
f"SERVER={settings.database_server},{settings.database_port};"
|
||||
f"DATABASE={settings.database_name};"
|
||||
f"UID={settings.database_user};"
|
||||
f"PWD={settings.database_password};"
|
||||
f"TrustServerCertificate=yes;"
|
||||
f"Connection Timeout=30;"
|
||||
)
|
||||
|
||||
@contextmanager
|
||||
def get_connection(self, server_type="main"):
|
||||
"""Context manager para manejar conexiones con cleanup automático"""
|
||||
connection = None
|
||||
try:
|
||||
server_name = "CONTROLDESK" if server_type == "main" else "BACKUP"
|
||||
self.logger.info(f"Estableciendo conexión con servidor {server_name}...")
|
||||
connection_string = self._build_connection_string(server_type)
|
||||
connection = pyodbc.connect(
|
||||
connection_string,
|
||||
timeout=30,
|
||||
autocommit=True
|
||||
)
|
||||
yield connection
|
||||
except pyodbc.Error as e:
|
||||
self.logger.error(f"Error de conexión SQL Server: {str(e)}")
|
||||
raise
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error inesperado en conexión: {str(e)}")
|
||||
raise
|
||||
finally:
|
||||
if connection:
|
||||
try:
|
||||
connection.close()
|
||||
self.logger.debug("Conexión cerrada correctamente")
|
||||
except Exception as e:
|
||||
self.logger.warning(f"Error al cerrar conexión: {str(e)}")
|
||||
|
||||
def execute_query(self, query: str, params: Optional[tuple] = None, server_type="main") -> List[Dict[str, Any]]:
|
||||
"""Ejecuta una consulta SELECT y retorna los resultados como lista de diccionarios"""
|
||||
try:
|
||||
with self.get_connection(server_type) as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
start_time = time.time()
|
||||
if params:
|
||||
cursor.execute(query, params)
|
||||
else:
|
||||
cursor.execute(query)
|
||||
|
||||
# Obtener nombres de columnas
|
||||
columns = [column[0] for column in cursor.description] if cursor.description else []
|
||||
|
||||
# Obtener filas y convertir a diccionarios
|
||||
rows = cursor.fetchall()
|
||||
results = []
|
||||
for row in rows:
|
||||
row_dict = {}
|
||||
for i, value in enumerate(row):
|
||||
if i < len(columns):
|
||||
row_dict[columns[i]] = value
|
||||
results.append(row_dict)
|
||||
|
||||
execution_time = time.time() - start_time
|
||||
self.logger.info(f"Consulta ejecutada en {execution_time:.3f}s. Filas: {len(results)}")
|
||||
|
||||
return results
|
||||
|
||||
except pyodbc.Error as e:
|
||||
self.logger.error(f"Error ejecutando consulta SQL: {str(e)}")
|
||||
self.logger.error(f"Query: {query}")
|
||||
if params:
|
||||
self.logger.error(f"Params: {params}")
|
||||
raise
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error inesperado ejecutando consulta: {str(e)}")
|
||||
raise
|
||||
|
||||
def test_connection(self, server_type="main") -> Dict[str, Any]:
|
||||
"""Prueba la conexión y retorna información del servidor"""
|
||||
try:
|
||||
with self.get_connection(server_type) as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Obtener información del servidor
|
||||
cursor.execute("SELECT @@VERSION as ServerVersion, DB_NAME() as DatabaseName, GETDATE() as CurrentTime")
|
||||
result = cursor.fetchone()
|
||||
|
||||
return {
|
||||
"status": "connected",
|
||||
"server_version": result.ServerVersion if result else "Unknown",
|
||||
"database_name": result.DatabaseName if result else "Unknown",
|
||||
"server_time": result.CurrentTime.isoformat() if result and result.CurrentTime else None,
|
||||
"connection_successful": True
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error probando conexión: {str(e)}")
|
||||
return {
|
||||
"status": "error",
|
||||
"error": str(e),
|
||||
"connection_successful": False
|
||||
}
|
||||
|
||||
|
||||
# Instancia global de la conexión
|
||||
db_connection = SQLServerConnection()
|
||||
Reference in New Issue
Block a user