| import glob |
| import json |
| import os |
|
|
| from app.db.models.app_config import AppConfig |
| from app.db.models.articles import ArticleItem, ArticleSubscription, ArticleSubscriptionItem |
| from app.db.models.download_job import DownloadJob |
| from app.db.models.models import Model |
| from app.db.models.note import Note |
| from app.db.models.providers import Provider |
| from app.db.models.trend_subscription import ( |
| NotificationChannel, |
| TrendSubscription, |
| TrendSubscriptionMatch, |
| ) |
| from app.db.models.video_tasks import VideoTask |
| from app.db.engine import get_engine, Base |
| from sqlalchemy import inspect, text |
|
|
| def init_db(): |
| engine = get_engine() |
|
|
| Base.metadata.create_all(bind=engine) |
| _ensure_article_content_text(engine) |
| _ensure_model_provider_id_text(engine) |
| _import_legacy_notes(engine) |
|
|
|
|
| |
| |
| |
| |
|
|
|
|
| def _ensure_model_provider_id_text(engine): |
| |
| |
| |
| |
| if engine.dialect.name != "postgresql": |
| return |
| inspector = inspect(engine) |
| if "models" not in inspector.get_table_names(): |
| return |
| for column in inspector.get_columns("models"): |
| if column["name"] != "provider_id": |
| continue |
| if "INT" in str(column["type"]).upper(): |
| with engine.begin() as conn: |
| conn.execute(text( |
| "ALTER TABLE models ALTER COLUMN provider_id TYPE VARCHAR " |
| "USING provider_id::varchar" |
| )) |
| break |
|
|
|
|
| def _import_legacy_notes(engine): |
| |
| |
| from app.db.note_dao import save_note, set_status |
|
|
| note_dir = os.getenv("NOTE_OUTPUT_DIR", "note_results") |
| if not os.path.isdir(note_dir): |
| return |
| try: |
| with engine.connect() as conn: |
| count = conn.execute(text("SELECT COUNT(*) FROM notes")).scalar() |
| if count and int(count) > 0: |
| return |
| except Exception: |
| return |
|
|
| imported = 0 |
| for path in glob.glob(os.path.join(note_dir, "*.json")): |
| name = os.path.basename(path) |
| stem = name[:-5] |
| |
| |
| if stem.endswith("_transcript") or stem.endswith("_audio") or "." in stem: |
| continue |
| try: |
| content = json.loads(open(path, "r", encoding="utf-8").read()) |
| except Exception: |
| continue |
| save_note(stem, content) |
| status_path = os.path.join(note_dir, f"{stem}.status.json") |
| if os.path.exists(status_path): |
| try: |
| set_status(stem, json.loads(open(status_path, "r", encoding="utf-8").read())) |
| except Exception: |
| pass |
| imported += 1 |
| if imported: |
| print(f"[init_db] 已从本地文件导入 {imported} 篇历史笔记到数据库") |
|
|
|
|
| def _ensure_article_content_text(engine): |
| inspector = inspect(engine) |
| if "article_items" not in inspector.get_table_names(): |
| return |
| columns = {column["name"] for column in inspector.get_columns("article_items")} |
| if "content_text" in columns: |
| return |
| with engine.begin() as conn: |
| conn.execute(text("ALTER TABLE article_items ADD COLUMN content_text TEXT NOT NULL DEFAULT ''")) |
|
|