Add File
This commit is contained in:
94
src/landppt/database/database.py
Normal file
94
src/landppt/database/database.py
Normal file
@@ -0,0 +1,94 @@
|
||||
"""
|
||||
Database configuration and session management
|
||||
"""
|
||||
|
||||
import os
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
|
||||
|
||||
from ..core.config import app_config
|
||||
|
||||
# Create database URL
|
||||
DATABASE_URL = app_config.database_url
|
||||
|
||||
# For async SQLite, we need to use aiosqlite
|
||||
if DATABASE_URL.startswith("sqlite:///"):
|
||||
ASYNC_DATABASE_URL = DATABASE_URL.replace("sqlite:///", "sqlite+aiosqlite:///")
|
||||
else:
|
||||
ASYNC_DATABASE_URL = DATABASE_URL
|
||||
|
||||
# Create engines
|
||||
# SQLite-specific configuration for better concurrency
|
||||
sqlite_connect_args = {
|
||||
"check_same_thread": False,
|
||||
"timeout": 30, # Wait up to 30 seconds for lock
|
||||
} if "sqlite" in DATABASE_URL else {}
|
||||
|
||||
engine = create_engine(
|
||||
DATABASE_URL,
|
||||
connect_args=sqlite_connect_args,
|
||||
echo=False, # Disable SQL logging to reduce noise
|
||||
pool_pre_ping=True, # Verify connections before using
|
||||
pool_size=100, # Larger pool for better concurrency
|
||||
max_overflow=200 # Allow overflow connections
|
||||
)
|
||||
|
||||
async_engine = create_async_engine(
|
||||
ASYNC_DATABASE_URL,
|
||||
echo=False, # Disable SQL logging to reduce noise
|
||||
pool_pre_ping=True,
|
||||
connect_args={"timeout": 30} if "sqlite" in ASYNC_DATABASE_URL else {}
|
||||
)
|
||||
|
||||
# Create session makers
|
||||
SessionLocal = sessionmaker(
|
||||
autocommit=False,
|
||||
autoflush=False,
|
||||
bind=engine,
|
||||
expire_on_commit=False # Prevent errors after commit
|
||||
)
|
||||
AsyncSessionLocal = async_sessionmaker(
|
||||
async_engine,
|
||||
class_=AsyncSession,
|
||||
expire_on_commit=False
|
||||
)
|
||||
|
||||
def get_db():
|
||||
"""Dependency to get database session"""
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
async def get_async_db():
|
||||
"""Dependency to get async database session"""
|
||||
async with AsyncSessionLocal() as session:
|
||||
yield session
|
||||
|
||||
|
||||
async def init_db():
|
||||
"""Initialize database tables"""
|
||||
# Import here to avoid circular imports
|
||||
from .models import Base
|
||||
|
||||
async with async_engine.begin() as conn:
|
||||
# Create all tables
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
|
||||
# Initialize default admin user
|
||||
from ..auth.auth_service import init_default_admin
|
||||
db = SessionLocal()
|
||||
try:
|
||||
init_default_admin(db)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
async def close_db():
|
||||
"""Close database connections"""
|
||||
await async_engine.dispose()
|
||||
|
||||
Reference in New Issue
Block a user