"""ORM模型定义""" from datetime import datetime from typing import Optional, List from sqlalchemy import String, Text, Integer, Float, Boolean, DateTime, ForeignKey from sqlalchemy.orm import relationship, Mapped, mapped_column from alcor.database import Base class Project(Base): """项目模型""" __tablename__ = "projects" id: Mapped[str] = mapped_column(String(64), primary_key=True) user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False, index=True) name: Mapped[str] = mapped_column(String(255), default="") description: Mapped[Optional[str]] = mapped_column(Text, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # 关系 user: Mapped["User"] = relationship("User", backref="projects") conversations: Mapped[List["Conversation"]] = relationship( "Conversation", back_populates="project", lazy="dynamic" ) def to_dict(self) -> dict: return { "id": self.id, "user_id": self.user_id, "name": self.name, "description": self.description, "created_at": self.created_at.isoformat() if self.created_at else None, "updated_at": self.updated_at.isoformat() if self.updated_at else None } class User(Base): """用户模型""" __tablename__ = "users" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) username: Mapped[str] = mapped_column(String(50), unique=True, nullable=False) email: Mapped[Optional[str]] = mapped_column(String(120), unique=True, nullable=True) password_hash: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) role: Mapped[str] = mapped_column(String(20), default="user") is_active: Mapped[bool] = mapped_column(Boolean, default=True) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) # 关系 conversations: Mapped[List["Conversation"]] = relationship( "Conversation", back_populates="user", lazy="dynamic" ) def to_dict(self) -> dict: return { "id": self.id, "username": self.username, "email": self.email, "role": self.role, "is_active": self.is_active, "created_at": self.created_at.isoformat() if self.created_at else None } class Conversation(Base): """会话模型""" __tablename__ = "conversations" id: Mapped[str] = mapped_column(String(64), primary_key=True) user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False, index=True) project_id: Mapped[Optional[str]] = mapped_column(String(64), ForeignKey("projects.id"), nullable=True) title: Mapped[str] = mapped_column(String(255), default="") model: Mapped[str] = mapped_column(String(64), default="glm-5") system_prompt: Mapped[str] = mapped_column(Text, default="") temperature: Mapped[float] = mapped_column(Float, default=1.0) max_tokens: Mapped[int] = mapped_column(Integer, default=65536) thinking_enabled: Mapped[bool] = mapped_column(Boolean, default=False) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # 关系 user: Mapped["User"] = relationship("User", back_populates="conversations") project: Mapped[Optional["Project"]] = relationship("Project", back_populates="conversations") messages: Mapped[List["Message"]] = relationship( "Message", back_populates="conversation", lazy="dynamic", cascade="all, delete-orphan", order_by="Message.created_at.asc()" ) def to_dict(self) -> dict: return { "id": self.id, "user_id": self.user_id, "project_id": self.project_id, "title": self.title, "model": self.model, "system_prompt": self.system_prompt, "temperature": self.temperature, "max_tokens": self.max_tokens, "thinking_enabled": self.thinking_enabled, "created_at": self.created_at.isoformat() if self.created_at else None, "updated_at": self.updated_at.isoformat() if self.updated_at else None } class Message(Base): """消息模型""" __tablename__ = "messages" id: Mapped[str] = mapped_column(String(64), primary_key=True) conversation_id: Mapped[str] = mapped_column( String(64), ForeignKey("conversations.id"), nullable=False, index=True ) role: Mapped[str] = mapped_column(String(16), nullable=False) # user, assistant, system, tool content: Mapped[str] = mapped_column(Text, default="") # JSON: {text, steps, tool_calls} token_count: Mapped[int] = mapped_column(Integer, default=0) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True) # 关系 conversation: Mapped["Conversation"] = relationship("Conversation", back_populates="messages") def to_dict(self) -> dict: return { "id": self.id, "conversation_id": self.conversation_id, "role": self.role, "content": self.content, "token_count": self.token_count, "created_at": self.created_at.isoformat() if self.created_at else None }