110 lines
3.8 KiB
Python
110 lines
3.8 KiB
Python
from sqlalchemy import Column, Integer, String, DateTime, Text
|
|
from sqlalchemy.ext.declarative import declarative_base
|
|
from sqlalchemy.orm import sessionmaker
|
|
from datetime import datetime
|
|
import json
|
|
|
|
from models.debate import DebateSession
|
|
from exceptions import ServiceNotConfiguredError
|
|
from services.config_service import ConfigService
|
|
|
|
Base = declarative_base()
|
|
|
|
|
|
class DebateSessionDB(Base):
|
|
__tablename__ = "debate_sessions"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
session_id = Column(String(255), unique=True, index=True, nullable=False)
|
|
topic = Column(Text, nullable=False)
|
|
participants = Column(Text, nullable=False) # JSON string
|
|
constraints = Column(Text, nullable=False) # JSON string
|
|
rounds = Column(Text, nullable=False) # JSON string
|
|
status = Column(String(50), nullable=False)
|
|
created_at = Column(DateTime, nullable=False)
|
|
completed_at = Column(DateTime, nullable=True)
|
|
summary = Column(Text, nullable=True)
|
|
evidence_library = Column(Text, nullable=True) # JSON string
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Lazy engine / session factory
|
|
# ---------------------------------------------------------------------------
|
|
_engine = None
|
|
_SessionLocal = None
|
|
|
|
|
|
def _get_engine():
|
|
from sqlalchemy import create_engine
|
|
global _engine
|
|
if _engine is None:
|
|
db_url = ConfigService.get_database_url()
|
|
if not db_url:
|
|
raise ServiceNotConfiguredError("数据库未配置")
|
|
_engine = create_engine(db_url)
|
|
return _engine
|
|
|
|
|
|
def _get_session_factory():
|
|
global _SessionLocal
|
|
if _SessionLocal is None:
|
|
_SessionLocal = sessionmaker(
|
|
autocommit=False, autoflush=False, bind=_get_engine()
|
|
)
|
|
return _SessionLocal
|
|
|
|
|
|
def init_db():
|
|
"""Create all tables if DB is configured; silently skip otherwise."""
|
|
if not ConfigService.is_db_configured():
|
|
print("WARNING: Database not configured, skipping table creation.")
|
|
return
|
|
try:
|
|
from db_models import Base as ApiBase
|
|
engine = _get_engine()
|
|
Base.metadata.create_all(bind=engine)
|
|
ApiBase.metadata.create_all(bind=engine)
|
|
except Exception as e:
|
|
global _engine, _SessionLocal
|
|
print(f"WARNING: Database connection failed, skipping table creation: {e}")
|
|
if _engine is not None:
|
|
_engine.dispose()
|
|
_engine = None
|
|
_SessionLocal = None
|
|
|
|
|
|
def debate_session_from_db(db_session) -> DebateSession:
|
|
"""Convert database session to Pydantic model."""
|
|
evidence_library = []
|
|
if db_session.evidence_library:
|
|
evidence_library = json.loads(db_session.evidence_library)
|
|
|
|
return DebateSession(
|
|
session_id=db_session.session_id,
|
|
topic=db_session.topic,
|
|
participants=json.loads(db_session.participants),
|
|
constraints=json.loads(db_session.constraints),
|
|
rounds=json.loads(db_session.rounds),
|
|
status=db_session.status,
|
|
created_at=db_session.created_at,
|
|
completed_at=db_session.completed_at,
|
|
summary=db_session.summary,
|
|
evidence_library=evidence_library
|
|
)
|
|
|
|
|
|
def debate_session_to_db(session: DebateSession) -> DebateSessionDB:
|
|
"""Convert Pydantic model to database model."""
|
|
return DebateSessionDB(
|
|
session_id=session.session_id,
|
|
topic=session.topic,
|
|
participants=json.dumps([p.dict() for p in session.participants]),
|
|
constraints=json.dumps(session.constraints.dict()),
|
|
rounds=json.dumps([r.dict() for r in session.rounds], default=str),
|
|
status=session.status,
|
|
created_at=session.created_at,
|
|
completed_at=session.completed_at,
|
|
summary=session.summary,
|
|
evidence_library=json.dumps([e.dict() for e in session.evidence_library], default=str) if session.evidence_library else None
|
|
)
|