web sttarting

This commit is contained in:
2026-03-31 13:25:14 +05:00
parent 9cd6d83428
commit 59b3bcd0f4
30 changed files with 720 additions and 242 deletions

View File

@@ -4,8 +4,8 @@ import importlib
from pathlib import Path
from typing import List
from bd import Settings
from sqlalchemy import create_engine, text
from bd import Settings, make_engine
from sqlalchemy import text
from sqlalchemy.exc import SQLAlchemyError
from pydantic import BaseModel
@@ -48,9 +48,7 @@ async def create_tables():
Endpoint вызывается по нажатию кнопки в UI (POST).
"""
settings = Settings()
db_url = settings.DATABASE_URL_syncpg
engine = create_engine(db_url, future=True)
engine = make_engine()
metadatas = collect_metadatas()
if not metadatas:
@@ -75,8 +73,7 @@ async def create_tables():
@router.post("/db/migrate-users", dependencies=[Depends(require_admin_key)])
async def migrate_users():
"""Добавляет колонки username и hashed_password в таблицу users, если они ещё не существуют."""
settings = Settings()
engine = create_engine(settings.DATABASE_URL_syncpg, future=True)
engine = make_engine()
try:
with engine.connect() as conn:
conn.execute(text("""
@@ -94,6 +91,30 @@ class ClearDBIn(BaseModel):
confirm: bool
@router.post("/db/migrate", dependencies=[Depends(require_admin_key)])
async def migrate_tables():
"""Приводит схему БД в соответствие с моделями: убирает устаревшие колонки, добавляет новые."""
engine = make_engine()
migrations = [
# Убираем старый FK и колонку group.user_id (если остался от прежней схемы)
'ALTER TABLE "group" DROP COLUMN IF EXISTS user_id',
# Делаем organization.group_id необязательным
"ALTER TABLE organization ALTER COLUMN group_id DROP NOT NULL",
# Добавляем новые колонки в users
'ALTER TABLE users ADD COLUMN IF NOT EXISTS group_id UUID REFERENCES "group"(id) ON DELETE SET NULL',
"ALTER TABLE users ADD COLUMN IF NOT EXISTS organization_id UUID REFERENCES organization(id) ON DELETE SET NULL",
]
applied = []
try:
with engine.begin() as conn:
for sql in migrations:
conn.execute(text(sql))
applied.append(sql)
return {"status": "ok", "applied": applied}
except SQLAlchemyError as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/db/clear", dependencies=[Depends(require_admin_key)])
async def clear_tables(payload: ClearDBIn):
"""Полная очистка всех таблиц, описанных в `bd.tables`.
@@ -103,9 +124,7 @@ async def clear_tables(payload: ClearDBIn):
if not payload.confirm:
raise HTTPException(status_code=400, detail="Confirmation required")
settings = Settings()
db_url = settings.DATABASE_URL_syncpg
engine = create_engine(db_url, future=True)
engine = make_engine()
metadatas = collect_metadatas()
if not metadatas:
@@ -120,8 +139,9 @@ async def clear_tables(payload: ClearDBIn):
unique.append(md)
try:
for md in unique:
md.drop_all(bind=engine)
return {"status": "ok", "detail": f"Dropped {len(unique)} metadata groups"}
with engine.begin() as conn:
conn.execute(text("DROP SCHEMA public CASCADE"))
conn.execute(text("CREATE SCHEMA public"))
return {"status": "ok", "detail": "All tables dropped via DROP SCHEMA CASCADE"}
except SQLAlchemyError as e:
raise HTTPException(status_code=500, detail=str(e))