fix: db
This commit is contained in:
@ -1,9 +1,11 @@
|
||||
"""Database models and session management."""
|
||||
import asyncio
|
||||
from typing import AsyncGenerator
|
||||
from sqlalchemy import create_engine, BigInteger, String, Integer, Boolean, ForeignKey, Column
|
||||
from sqlalchemy.orm import declarative_base, sessionmaker, relationship, Session
|
||||
from sqlalchemy.schema import UniqueConstraint
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
|
||||
import socket
|
||||
from bot.config import Config
|
||||
from bot.logger import get_logger
|
||||
|
||||
@ -68,7 +70,23 @@ class UserChat(Base):
|
||||
# Database engine and session (async)
|
||||
# Convert postgresql:// to postgresql+asyncpg://
|
||||
async_database_url = Config.DATABASE_URL.replace("postgresql://", "postgresql+asyncpg://", 1)
|
||||
async_engine = create_async_engine(async_database_url, echo=False)
|
||||
|
||||
# Configure connection pool with better timeout settings
|
||||
async_engine = create_async_engine(
|
||||
async_database_url,
|
||||
echo=False,
|
||||
pool_pre_ping=True, # Verify connections before using them
|
||||
pool_size=5, # Number of connections to maintain
|
||||
max_overflow=10, # Maximum overflow connections
|
||||
pool_recycle=3600, # Recycle connections after 1 hour
|
||||
pool_timeout=30, # Timeout for getting connection from pool
|
||||
connect_args={
|
||||
"server_settings": {
|
||||
"application_name": "bdbot",
|
||||
},
|
||||
"command_timeout": 60, # Command timeout
|
||||
}
|
||||
)
|
||||
AsyncSessionLocal = async_sessionmaker(async_engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
|
||||
@ -82,12 +100,30 @@ async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
||||
|
||||
|
||||
async def init_db() -> None:
|
||||
"""Initialize database - create all tables."""
|
||||
"""Initialize database - create all tables with retry logic."""
|
||||
logger.info("Initializing database...")
|
||||
|
||||
max_retries = 5
|
||||
base_delay = 2 # Start with 2 seconds
|
||||
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
async with async_engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
logger.info("Database initialized successfully")
|
||||
return
|
||||
except (socket.gaierror, OSError) as e:
|
||||
# DNS resolution or network errors
|
||||
if attempt < max_retries - 1:
|
||||
delay = base_delay * (2 ** attempt) # Exponential backoff: 2, 4, 8, 16, 32
|
||||
logger.warning(
|
||||
f"Database connection failed (attempt {attempt + 1}/{max_retries}): {e}. "
|
||||
f"Retrying in {delay} seconds..."
|
||||
)
|
||||
await asyncio.sleep(delay)
|
||||
else:
|
||||
logger.error(f"Failed to connect to database after {max_retries} attempts: {e}", exc_info=True)
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Error initializing database: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
@ -1 +0,0 @@
|
||||
# Handlers package
|
||||
Reference in New Issue
Block a user