Files
skill-template/content-manager/content_manager/db/connection.py
2026-04-04 10:35:02 +08:00

114 lines
3.5 KiB
Python

"""数据库连接与初始化(建表、文章旧库迁移、提示词种子)。"""
from __future__ import annotations
import sqlite3
from typing import TYPE_CHECKING
from content_manager.config import get_db_path
from content_manager.db.schema import (
ARTICLES_TABLE_SQL,
IMAGES_TABLE_SQL,
PROMPT_TEMPLATE_USAGE_TABLE_SQL,
PROMPT_TEMPLATES_TABLE_SQL,
VIDEOS_TABLE_SQL,
)
from content_manager.util.timeutil import now_unix, parse_ts_to_unix
if TYPE_CHECKING:
pass
def get_conn() -> sqlite3.Connection:
return sqlite3.connect(get_db_path())
def _is_legacy_articles_table(cur: sqlite3.Cursor) -> bool:
cur.execute("PRAGMA table_info(articles)")
rows = cur.fetchall()
if not rows:
return False
for _cid, name, ctype, _nn, _d, _pk in rows:
if name == "id" and ctype and ctype.upper() == "INTEGER":
return False
cur.execute("SELECT sql FROM sqlite_master WHERE type='table' AND name='articles'")
row = cur.fetchone()
if row and row[0] and "TEXT" in row[0] and "id" in row[0]:
return True
return False
def _migrate_legacy_articles(conn: sqlite3.Connection) -> None:
cur = conn.cursor()
cur.executescript(
"""
CREATE TABLE _articles_migrated (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
body TEXT NOT NULL,
content_html TEXT,
status TEXT NOT NULL DEFAULT 'draft',
source TEXT NOT NULL DEFAULT 'manual',
account_id TEXT,
error_msg TEXT,
llm_target TEXT,
extra_json TEXT,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
"""
)
cur.execute(
"SELECT id, title, content, content_html, status, account_id, error_msg, created_at, updated_at FROM articles"
)
ts = now_unix()
for row in cur.fetchall():
_oid, title, content, content_html, status, account_id, error_msg, cat, uat = row
body = content or ""
ch = content_html if content_html else None
cts = parse_ts_to_unix(cat) or ts
uts = parse_ts_to_unix(uat) or ts
cur.execute(
"""
INSERT INTO _articles_migrated (
title, body, content_html, status, source, account_id, error_msg,
created_at, updated_at
) VALUES (?, ?, ?, ?, 'import', ?, ?, ?, ?)
""",
(
title or "",
body,
ch,
(status or "draft"),
account_id,
error_msg,
cts,
uts,
),
)
cur.execute("DROP TABLE articles")
cur.execute("ALTER TABLE _articles_migrated RENAME TO articles")
conn.commit()
def init_db() -> None:
conn = get_conn()
try:
cur = conn.cursor()
cur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='articles'")
if cur.fetchone():
if _is_legacy_articles_table(cur):
_migrate_legacy_articles(conn)
else:
cur.executescript(ARTICLES_TABLE_SQL)
cur.executescript(IMAGES_TABLE_SQL)
cur.executescript(VIDEOS_TABLE_SQL)
cur.executescript(PROMPT_TEMPLATES_TABLE_SQL)
cur.executescript(PROMPT_TEMPLATE_USAGE_TABLE_SQL)
from content_manager.db.prompts_repository import seed_prompt_templates_if_empty
seed_prompt_templates_if_empty(conn.cursor())
conn.commit()
finally:
conn.close()