fix data base
This commit is contained in:
69
route/init_data_base.py
Normal file
69
route/init_data_base.py
Normal file
@@ -0,0 +1,69 @@
|
||||
from fastapi import APIRouter, HTTPException
|
||||
import pkgutil
|
||||
import importlib
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from bd import Settings
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
router = APIRouter(tags=["db"])
|
||||
|
||||
|
||||
def _iter_table_modules() -> List[str]:
|
||||
try:
|
||||
import bd.tables as tables_pkg
|
||||
pkg_paths = getattr(tables_pkg, "__path__", None)
|
||||
if not pkg_paths:
|
||||
pkg_paths = [str(Path(__file__).resolve().parent.parent / "bd" / "tables")]
|
||||
except Exception:
|
||||
pkg_paths = [str(Path(__file__).resolve().parent.parent / "bd" / "tables")]
|
||||
|
||||
names = []
|
||||
for finder, name, ispkg in pkgutil.iter_modules(pkg_paths):
|
||||
names.append(name)
|
||||
return names
|
||||
|
||||
|
||||
def collect_metadatas():
|
||||
metadatas = []
|
||||
for mod_name in _iter_table_modules():
|
||||
try:
|
||||
module = importlib.import_module(f"bd.tables.{mod_name}")
|
||||
except Exception:
|
||||
continue
|
||||
Base = getattr(module, "Base", None)
|
||||
if Base is not None and hasattr(Base, "metadata"):
|
||||
metadatas.append(Base.metadata)
|
||||
return metadatas
|
||||
|
||||
|
||||
@router.post("/db/create-tables")
|
||||
async def create_tables():
|
||||
"""Создаёт все таблицы, описанные в модулях `db.tables`.
|
||||
|
||||
Endpoint вызывается по нажатию кнопки в UI (POST).
|
||||
"""
|
||||
settings = Settings()
|
||||
db_url = settings.DATABASE_URL_syncpg
|
||||
engine = create_engine(db_url, future=True)
|
||||
|
||||
metadatas = collect_metadatas()
|
||||
if not metadatas:
|
||||
raise HTTPException(status_code=400, detail="No table metadata found in db.tables")
|
||||
|
||||
# deduplicate metadata objects (multiple modules may expose the same Base.metadata)
|
||||
unique = []
|
||||
seen = set()
|
||||
for md in metadatas:
|
||||
if id(md) not in seen:
|
||||
seen.add(id(md))
|
||||
unique.append(md)
|
||||
|
||||
try:
|
||||
for md in unique:
|
||||
md.create_all(bind=engine)
|
||||
return {"status": "ok", "detail": f"Created {len(unique)} metadata groups"}
|
||||
except SQLAlchemyError as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
Reference in New Issue
Block a user