Files
HuiBrain/app/models/base.py
EduBrain Dev 496e11e26e refactor: 移除 PostgreSQL 支持,简化为纯 SQLite 部署
- config.py: DATABASE_URL 默认值改为 SQLite
- database.py: 移除 PostgreSQL 分支,简化为纯 SQLite
- models/base.py: 移除 pgvector 导入和条件分支
- search_service.py: 移除 _search_postgres 方法
- import_service.py: 移除 pgvector 相关代码
- requirements.txt: 移除 asyncpg/alembic/pgvector 依赖
- pyproject.toml: 同步移除相关依赖
- docker-compose.yml: 移除 db 服务,- 删除 alembic.ini/Dockerfile.db/sql 目录
- README.md: 更新文档,移除 PostgreSQL 相关内容

适合 NAS 等资源受限环境的轻量级部署
2026-04-14 14:50:53 +08:00

103 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
ORM 模型定义
SQLite 数据库模型,使用 Text 存储 JSON 格式的向量。
"""
from __future__ import annotations
import json
from datetime import datetime
from typing import Any, Dict
from sqlalchemy import DateTime, Float, Integer, String, Text, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
"""所有 ORM 模型的基类"""
pass
class TimestampMixin:
"""时间戳 Mixin"""
created_at: Mapped[datetime] = mapped_column(
DateTime, default=func.now(), comment="创建时间"
)
updated_at: Mapped[datetime] = mapped_column(
DateTime, default=func.now(), onupdate=func.now(), comment="更新时间"
)
class KnowledgePage(Base, TimestampMixin):
"""知识页面"""
__tablename__ = "knowledge_pages"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
title: Mapped[str] = mapped_column(String(500), nullable=False, comment="页面标题")
content: Mapped[str] = mapped_column(Text, nullable=False, comment="页面内容")
source: Mapped[str | None] = mapped_column(String(200), nullable=True, comment="来源文件名")
page_number: Mapped[int | None] = mapped_column(Integer, nullable=True, comment="原文件页码")
# 向量嵌入JSON 格式存储)
embedding: Mapped[str | None] = mapped_column(Text, nullable=True, comment="向量嵌入JSON")
@property
def embedding_vector(self) -> list[float] | None:
if self.embedding is None:
return None
return json.loads(self.embedding)
@embedding_vector.setter
def embedding_vector(self, value: list[float] | None):
self.embedding = json.dumps(value) if value else None
class OCRImage(Base, TimestampMixin):
"""OCR 图片记录"""
__tablename__ = "ocr_images"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
file_path: Mapped[str] = mapped_column(String(500), nullable=False, comment="图片文件路径")
original_filename: Mapped[str | None] = mapped_column(String(200), nullable=True, comment="原始文件名")
ocr_text: Mapped[str | None] = mapped_column(Text, nullable=True, comment="OCR 识别文本")
confidence: Mapped[float | None] = mapped_column(Float, nullable=True, comment="OCR 置信度")
provider: Mapped[str | None] = mapped_column(String(50), nullable=True, comment="OCR 提供商")
status: Mapped[str] = mapped_column(
String(20), default="pending", comment="状态: pending/processing/completed/failed"
)
tags: Mapped[str | None] = mapped_column(Text, nullable=True, comment="关键词标签JSON 数组)")
story_summary: Mapped[str | None] = mapped_column(Text, nullable=True, comment="故事摘要")
blocks: Mapped[str | None] = mapped_column(Text, nullable=True, comment="OCR 文本块JSON")
@property
def tags_list(self) -> list[str]:
if self.tags is None:
return []
return json.loads(self.tags)
@tags_list.setter
def tags_list(self, value: list[str]):
self.tags = json.dumps(value) if value else None
@property
def blocks_list(self) -> list[dict]:
if self.blocks is None:
return []
return json.loads(self.blocks)
@blocks_list.setter
def blocks_list(self, value: list[dict]):
self.blocks = json.dumps(value) if value else None
class WebsiteSettings(Base):
"""网站设置(单例)"""
__tablename__ = "website_settings"
key: Mapped[str] = mapped_column(String(100), primary_key=True, comment="设置键")
value: Mapped[str | None] = mapped_column(Text, nullable=True, comment="设置值JSON")
updated_at: Mapped[datetime] = mapped_column(
DateTime, default=func.now(), onupdate=func.now(), comment="更新时间"
)