128 lines
4.1 KiB
Python
128 lines
4.1 KiB
Python
from typing import AsyncGenerator
|
|
|
|
from sqlalchemy import text
|
|
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
|
|
from sqlalchemy.orm import declarative_base
|
|
|
|
from app.core.config import settings
|
|
|
|
engine = create_async_engine(
|
|
settings.DATABASE_URL,
|
|
echo=settings.DEBUG if hasattr(settings, "DEBUG") else False,
|
|
)
|
|
|
|
async_session_factory = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
|
|
|
Base = declarative_base()
|
|
|
|
|
|
async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
|
async with async_session_factory() as session:
|
|
try:
|
|
yield session
|
|
await session.commit()
|
|
except Exception:
|
|
await session.rollback()
|
|
raise
|
|
|
|
|
|
async def seed_default_datasources(session: AsyncSession):
|
|
from app.core.datasource_defaults import DEFAULT_DATASOURCES
|
|
from app.models.datasource import DataSource
|
|
|
|
for source, info in DEFAULT_DATASOURCES.items():
|
|
existing = await session.get(DataSource, info["id"])
|
|
if existing:
|
|
existing.name = info["name"]
|
|
existing.source = source
|
|
existing.module = info["module"]
|
|
existing.priority = info["priority"]
|
|
existing.frequency_minutes = info["frequency_minutes"]
|
|
existing.collector_class = source
|
|
if existing.config is None:
|
|
existing.config = "{}"
|
|
continue
|
|
|
|
session.add(
|
|
DataSource(
|
|
id=info["id"],
|
|
name=info["name"],
|
|
source=source,
|
|
module=info["module"],
|
|
priority=info["priority"],
|
|
frequency_minutes=info["frequency_minutes"],
|
|
collector_class=source,
|
|
config="{}",
|
|
is_active=True,
|
|
)
|
|
)
|
|
|
|
await session.commit()
|
|
|
|
|
|
async def init_db():
|
|
import app.models.user # noqa: F401
|
|
import app.models.gpu_cluster # noqa: F401
|
|
import app.models.task # noqa: F401
|
|
import app.models.data_snapshot # noqa: F401
|
|
import app.models.datasource # noqa: F401
|
|
import app.models.datasource_config # noqa: F401
|
|
import app.models.alert # noqa: F401
|
|
import app.models.collected_data # noqa: F401
|
|
import app.models.system_setting # noqa: F401
|
|
|
|
async with engine.begin() as conn:
|
|
await conn.run_sync(Base.metadata.create_all)
|
|
await conn.execute(
|
|
text(
|
|
"""
|
|
ALTER TABLE collected_data
|
|
ADD COLUMN IF NOT EXISTS snapshot_id INTEGER,
|
|
ADD COLUMN IF NOT EXISTS task_id INTEGER,
|
|
ADD COLUMN IF NOT EXISTS entity_key VARCHAR(255),
|
|
ADD COLUMN IF NOT EXISTS is_current BOOLEAN DEFAULT TRUE,
|
|
ADD COLUMN IF NOT EXISTS previous_record_id INTEGER,
|
|
ADD COLUMN IF NOT EXISTS change_type VARCHAR(20),
|
|
ADD COLUMN IF NOT EXISTS change_summary JSONB DEFAULT '{}'::jsonb,
|
|
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ
|
|
"""
|
|
)
|
|
)
|
|
await conn.execute(
|
|
text(
|
|
"""
|
|
ALTER TABLE collection_tasks
|
|
ADD COLUMN IF NOT EXISTS phase VARCHAR(30) DEFAULT 'queued'
|
|
"""
|
|
)
|
|
)
|
|
await conn.execute(
|
|
text(
|
|
"""
|
|
CREATE INDEX IF NOT EXISTS idx_collected_data_source_source_id
|
|
ON collected_data (source, source_id)
|
|
"""
|
|
)
|
|
)
|
|
await conn.execute(
|
|
text(
|
|
"""
|
|
UPDATE collected_data
|
|
SET entity_key = source || ':' || COALESCE(source_id, id::text)
|
|
WHERE entity_key IS NULL
|
|
"""
|
|
)
|
|
)
|
|
await conn.execute(
|
|
text(
|
|
"""
|
|
UPDATE collected_data
|
|
SET is_current = TRUE
|
|
WHERE is_current IS NULL
|
|
"""
|
|
)
|
|
)
|
|
|
|
async with async_session_factory() as session:
|
|
await seed_default_datasources(session)
|