| |
| """ |
| 数据库模型定义。 |
| 使用 SQLAlchemy 定义与数据库表对应的 Python 类。 |
| """ |
| from sqlalchemy.ext.declarative import declarative_base |
| from sqlalchemy import Column, Integer, String, Float, DateTime, Text, Boolean, func |
| from sqlalchemy.orm import sessionmaker |
| from datetime import datetime, timezone |
| import pytz |
| import logging |
|
|
| |
| logger = logging.getLogger('my_logger') |
|
|
| |
| Base = declarative_base() |
|
|
| class ApiKey(Base): |
| """ |
| API 密钥模型,用于在数据库中存储 API Key 的信息。 |
| 对应数据库中的 'api_keys' 表。 |
| """ |
| __tablename__ = 'api_keys' |
|
|
| id = Column(Integer, primary_key=True, autoincrement=True) |
| key_string = Column(String, nullable=False, unique=True, index=True) |
| description = Column(String, nullable=True) |
| created_at = Column(DateTime(timezone=True), server_default=func.now()) |
| expires_at = Column(DateTime(timezone=True), nullable=True) |
| is_active = Column(Boolean, default=True, nullable=False) |
| enable_context_completion = Column(Boolean, default=True, nullable=False) |
| user_id = Column(String, nullable=True, index=True) |
|
|
| def __repr__(self): |
| """ |
| 定义对象的字符串表示形式,方便调试。 |
| 隐藏完整的 Key 字符串,只显示前缀。 |
| """ |
| |
| key_preview = f"{self.key_string[:8]}..." if self.key_string else "None" |
| return f'<ApiKey(id={self.id}, key_preview={key_preview}, description={self.description}, is_active={self.is_active})>' |
|
|
|
|
| class UserKeyAssociation(Base): |
| """ |
| 用户与 API 密钥关联模型。 |
| 用于记录哪个用户最后使用了哪个 Key,支持粘性会话功能。 |
| 对应数据库中的 'user_key_associations' 表。 |
| """ |
| __tablename__ = 'user_key_associations' |
| id = Column(Integer, primary_key=True, autoincrement=True) |
| user_id = Column(String, nullable=False, index=True) |
| key_id = Column(Integer, nullable=False, index=True) |
| last_used_timestamp = Column(Float, nullable=False) |
|
|
| def __repr__(self): |
| """ |
| 定义对象的字符串表示形式。 |
| """ |
| return f'<UserKeyAssociation(user_id={self.user_id}, key_id={self.key_id}, last_used={self.last_used_timestamp})>' |
|
|
|
|
| class KeyScore(Base): |
| """ |
| API 密钥分数模型 (目前可能未使用)。 |
| 设计用于存储每个 Key 对不同模型的评分或优先级。 |
| 对应数据库中的 'key_scores' 表。 |
| """ |
| __tablename__ = 'key_scores' |
| id = Column(Integer, primary_key=True, autoincrement=True) |
| model_name = Column(String, nullable=False, index=True) |
| key_id = Column(Integer, nullable=False, index=True) |
| score = Column(Float, nullable=False) |
|
|
| def __repr__(self): |
| """ |
| 定义对象的字符串表示形式。 |
| """ |
| return f'<KeyScore(model_name={self.model_name}, key_id={self.key_id}, score={self.score})>' |
|
|
| class CachedContent(Base): |
| """ |
| 缓存内容模型。 |
| 用于存储原生缓存的数据。 |
| 对应数据库中的 'cached_contents' 表。 |
| """ |
| __tablename__ = 'cached_contents' |
| id = Column(Integer, primary_key=True, autoincrement=True) |
| content_id = Column(String, nullable=False, unique=True, index=True) |
| content = Column(Text, nullable=False) |
| user_id = Column(String, nullable=True, index=True) |
| key_id = Column(Integer, nullable=True, index=True) |
| creation_timestamp = Column(Float, nullable=False) |
| expiration_timestamp = Column(Float, nullable=False) |
| gemini_cache_id = Column(String, nullable=True, index=True) |
|
|
| def __repr__(self): |
| """ |
| 定义对象的字符串表示形式。 |
| """ |
| return f'<CachedContent(content_id={self.content_id}, creation_timestamp={self.creation_timestamp}, expiration_timestamp={self.expiration_timestamp})>' |
|
|
| class Setting(Base): |
| """ |
| 设置模型,用于存储应用程序的键值对设置。 |
| 例如,可以存储管理员密码或其他配置项。 |
| 对应数据库中的 'settings' 表。 |
| """ |
| __tablename__ = 'settings' |
| key = Column(String, primary_key=True) |
| value = Column(String) |
|
|
| def __repr__(self): |
| """ |
| 定义对象的字符串表示形式。 |
| """ |
| return f'<Setting(key={self.key}, value={self.value})>' |
|
|
| class DialogContext(Base): |
| """ |
| 传统对话上下文存储模型。 |
| 对应数据库中的 'dialog_contexts' 表。 |
| """ |
| __tablename__ = 'dialog_contexts' |
|
|
| id = Column(Integer, primary_key=True, autoincrement=True) |
| |
| proxy_key = Column(String, nullable=False, index=True) |
| |
| contents = Column(Text, nullable=False) |
| |
| last_used_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()) |
| |
| created_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now()) |
| |
| ttl_seconds = Column(Integer, nullable=True) |
|
|
| def __repr__(self): |
| """ |
| 定义对象的字符串表示形式,方便调试。 |
| """ |
| return f'<DialogContext(id={self.id}, proxy_key={self.proxy_key}, last_used_at={self.last_used_at})>' |
|
|
| |
| |
| |
|
|
| def create_session(engine): |
| """ |
| (可能已废弃) 创建一个同步的 SQLAlchemy 数据库会话。 |
| 注意:项目主要使用异步会话。 |
| """ |
| logger.warning("调用了可能已废弃的同步 create_session 函数。") |
| SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) |
| return SessionLocal() |
|
|
| async def create_db_engine(): |
| """ |
| (可能已废弃) 创建一个 aiosqlite 数据库连接(引擎)。 |
| 注意:项目现在可能使用 SQLAlchemy 的异步引擎。 |
| """ |
| logger.warning("调用了可能已废弃的 create_db_engine 函数 (aiosqlite)。") |
| import aiosqlite |
| |
| engine = await aiosqlite.connect('app/data/context_store.db', uri=True) |
| return engine |
|
|
| async def close_db_engine(engine): |
| """ |
| (可能已废弃) 关闭一个 aiosqlite 数据库连接(引擎)。 |
| """ |
| logger.warning("调用了可能已废弃的 close_db_engine 函数 (aiosqlite)。") |
| await engine.close() |
|
|