101 lines
2.5 KiB
Python
101 lines
2.5 KiB
Python
"""初始化 novel-app 数据库:创建表与索引。
|
||
|
||
用法:python3 scripts/init_db.py(可从任意目录运行)。
|
||
"""
|
||
|
||
import os
|
||
import sqlite3
|
||
import sys
|
||
|
||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||
|
||
import config
|
||
|
||
SCHEMA = """
|
||
CREATE TABLE IF NOT EXISTS novels (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
title TEXT NOT NULL,
|
||
genre TEXT,
|
||
style TEXT,
|
||
target_words INTEGER,
|
||
current_words INTEGER DEFAULT 0,
|
||
status TEXT DEFAULT 'planning',
|
||
created_at TEXT, updated_at TEXT
|
||
);
|
||
CREATE TABLE IF NOT EXISTS chapters (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
novel_id INTEGER REFERENCES novels(id),
|
||
volume INTEGER,
|
||
chapter_number INTEGER,
|
||
title TEXT,
|
||
outline TEXT,
|
||
content TEXT,
|
||
word_count INTEGER,
|
||
status TEXT DEFAULT 'pending',
|
||
created_at TEXT, updated_at TEXT
|
||
);
|
||
CREATE TABLE IF NOT EXISTS characters (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
novel_id INTEGER REFERENCES novels(id),
|
||
name TEXT NOT NULL,
|
||
role TEXT,
|
||
description TEXT,
|
||
first_appearance_chapter INTEGER,
|
||
status TEXT DEFAULT 'alive',
|
||
created_at TEXT, updated_at TEXT
|
||
);
|
||
CREATE TABLE IF NOT EXISTS foreshadowing (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
novel_id INTEGER REFERENCES novels(id),
|
||
description TEXT,
|
||
planted_chapter INTEGER,
|
||
resolved_chapter INTEGER,
|
||
status TEXT DEFAULT 'pending',
|
||
created_at TEXT, updated_at TEXT
|
||
);
|
||
CREATE TABLE IF NOT EXISTS jobs (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
novel_id INTEGER REFERENCES novels(id),
|
||
job_type TEXT,
|
||
status TEXT DEFAULT 'pending',
|
||
input_json TEXT,
|
||
output_json TEXT,
|
||
error TEXT,
|
||
created_at TEXT, completed_at TEXT
|
||
);
|
||
"""
|
||
|
||
INDEXES = """
|
||
CREATE INDEX IF NOT EXISTS idx_chapters_novel ON chapters(novel_id, volume, chapter_number);
|
||
CREATE INDEX IF NOT EXISTS idx_characters_novel ON characters(novel_id);
|
||
CREATE INDEX IF NOT EXISTS idx_foreshadowing_novel ON foreshadowing(novel_id);
|
||
CREATE INDEX IF NOT EXISTS idx_jobs_novel ON jobs(novel_id);
|
||
"""
|
||
|
||
|
||
def main():
|
||
db_path = config.DB_PATH
|
||
os.makedirs(os.path.dirname(db_path) or ".", exist_ok=True)
|
||
|
||
conn = sqlite3.connect(db_path)
|
||
try:
|
||
conn.executescript(SCHEMA)
|
||
conn.executescript(INDEXES)
|
||
conn.commit()
|
||
|
||
tables = [
|
||
r[0]
|
||
for r in conn.execute(
|
||
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
|
||
)
|
||
]
|
||
print(f"Database initialized at: {db_path}")
|
||
print("Tables:")
|
||
for t in tables:
|
||
print(f" - {t}")
|
||
finally:
|
||
conn.close()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main() |