product
This commit is contained in:
123
db/oracle_connector.py
Normal file
123
db/oracle_connector.py
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Oracle database connection pool manager using oracledb.
|
||||
Manages connections with pooling and health checks.
|
||||
|
||||
oracledb is the modern, simpler replacement for cx_Oracle.
|
||||
No Oracle Instant Client required - uses Thick or Thin mode.
|
||||
"""
|
||||
|
||||
import oracledb
|
||||
from logging_config import get_logger
|
||||
from config import get_config
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class OracleConnector:
|
||||
"""Manages Oracle database connections with pooling."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize connection pool."""
|
||||
self.pool = None
|
||||
self.config = get_config()
|
||||
self._initialize_client_mode()
|
||||
|
||||
def _initialize_client_mode(self):
|
||||
"""
|
||||
Initialize oracledb client mode.
|
||||
oracledb uses Thin mode by default (no Oracle Instant Client needed).
|
||||
"""
|
||||
try:
|
||||
# oracledb defaults to Thin mode - no initialization needed
|
||||
logger.info("Using oracledb Thin mode (no Oracle Instant Client required)")
|
||||
except Exception as e:
|
||||
logger.warning(f"Oracle client initialization note: {e}")
|
||||
|
||||
def initialize_pool(self):
|
||||
"""Create connection pool."""
|
||||
try:
|
||||
# Build connection string for oracledb
|
||||
# Format: user/password@host:port/service_name
|
||||
connection_string = (
|
||||
f"{self.config.db_user}/{self.config.db_password}@"
|
||||
f"{self.config.db_host}:{self.config.db_port}/{self.config.db_service_name}"
|
||||
)
|
||||
|
||||
# Create connection pool using oracledb API
|
||||
# Note: oracledb uses 'min' and 'max' for pool sizing
|
||||
self.pool = oracledb.create_pool(
|
||||
dsn=connection_string,
|
||||
min=self.config.db_pool_min,
|
||||
max=self.config.db_pool_max,
|
||||
increment=1,
|
||||
)
|
||||
|
||||
logger.info(f"Oracle connection pool initialized: min={self.config.db_pool_min}, max={self.config.db_pool_max}")
|
||||
return True
|
||||
except oracledb.DatabaseError as e:
|
||||
logger.error(f"Failed to initialize connection pool: {e}", exc_info=True)
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error initializing pool: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
def get_connection(self):
|
||||
"""Get connection from pool."""
|
||||
if not self.pool:
|
||||
self.initialize_pool()
|
||||
|
||||
try:
|
||||
conn = self.pool.acquire()
|
||||
logger.debug("Connection acquired from pool")
|
||||
return conn
|
||||
except oracledb.DatabaseError as e:
|
||||
logger.error(f"Failed to acquire connection: {e}", exc_info=True)
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error acquiring connection: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def close_pool(self):
|
||||
"""Close connection pool."""
|
||||
if self.pool:
|
||||
try:
|
||||
self.pool.close()
|
||||
logger.info("Connection pool closed")
|
||||
except Exception as e:
|
||||
logger.error(f"Error closing pool: {e}")
|
||||
|
||||
def test_connection(self):
|
||||
"""Test database connectivity."""
|
||||
try:
|
||||
conn = self.get_connection()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT 1 FROM dual")
|
||||
result = cursor.fetchone()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
logger.info("Database connection test successful")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Database connection test failed: {e}")
|
||||
return False
|
||||
|
||||
def __enter__(self):
|
||||
"""Context manager entry."""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
"""Context manager exit."""
|
||||
self.close_pool()
|
||||
|
||||
|
||||
# Global connector instance
|
||||
_connector = None
|
||||
|
||||
|
||||
def get_connector():
|
||||
"""Get or create global connector instance."""
|
||||
global _connector
|
||||
if _connector is None:
|
||||
_connector = OracleConnector()
|
||||
return _connector
|
||||
Reference in New Issue
Block a user