from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker from sqlalchemy.orm import DeclarativeBase from backend.config import get_settings settings = get_settings() engine = create_async_engine(settings.database_url, echo=False) async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False) class Base(DeclarativeBase): pass async def get_db(): async with async_session() as session: try: yield session await session.commit() except Exception: await session.rollback() raise async def init_db(): async with engine.begin() as conn: # 迁移旧表:acme_config → acme_configs try: result = await conn.execute( __import__("sqlalchemy").text("SELECT name FROM sqlite_master WHERE type='table' AND name='acme_config'") ) if result.fetchone(): await conn.execute(__import__("sqlalchemy").text("ALTER TABLE acme_config RENAME TO acme_configs")) except Exception: pass await conn.run_sync(Base.metadata.create_all) # 迁移:给 domains 表加 acme_config_id 列 try: await conn.execute( __import__("sqlalchemy").text("ALTER TABLE domains ADD COLUMN acme_config_id INTEGER REFERENCES acme_configs(id)") ) except Exception: pass # 列已存在 # 确保至少有一条默认配置 result = await conn.execute( __import__("sqlalchemy").text("SELECT COUNT(*) FROM acme_configs") ) count = result.scalar() if count == 0: await conn.execute( __import__("sqlalchemy").text( "INSERT INTO acme_configs (name, acme_server, email, dns_provider, dns_credentials, renew_days) " "VALUES ('默认配置', 'https://acme-v02.api.letsencrypt.org/directory', '', 'aliyun', '{}', 30)" ) )