#!/usr/bin/env python3 """ 数据库迁移脚本:创建 news_articles 表 使用方法: python scripts/migrate_create_news_table.py 或者在服务器上直接执行 SQL(参考 schema.sql) """ import sqlite3 import os from pathlib import Path # SQL 建表语句 CREATE_TABLE_SQL = """ CREATE TABLE IF NOT EXISTS news_articles ( id INTEGER PRIMARY KEY AUTOINCREMENT, title VARCHAR(500) NOT NULL, content TEXT, content_hash VARCHAR(64) NOT NULL, url VARCHAR(1000) NOT NULL UNIQUE, source VARCHAR(100) NOT NULL, author VARCHAR(200), category VARCHAR(50) NOT NULL, tags JSON, published_at DATETIME, crawled_at DATETIME NOT NULL, llm_analyzed BOOLEAN DEFAULT 0, market_impact VARCHAR(20), impact_type VARCHAR(50), relevant_symbols JSON, sentiment VARCHAR(20), summary TEXT, key_points JSON, trading_advice TEXT, priority REAL DEFAULT 0.0, priority_reason TEXT, notified BOOLEAN DEFAULT 0, notification_sent_at DATETIME, notification_channel VARCHAR(50), quality_score REAL, duplicate_of INTEGER, is_active BOOLEAN DEFAULT 1, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL ); -- 创建索引 CREATE INDEX IF NOT EXISTS idx_news_articles_content_hash ON news_articles(content_hash); CREATE INDEX IF NOT EXISTS idx_news_articles_category ON news_articles(category); CREATE INDEX IF NOT EXISTS idx_news_articles_published_at ON news_articles(published_at); CREATE INDEX IF NOT EXISTS idx_news_articles_crawled_at ON news_articles(crawled_at); CREATE INDEX IF NOT EXISTS idx_news_articles_llm_analyzed ON news_articles(llm_analyzed); CREATE INDEX IF NOT EXISTS idx_news_articles_priority ON news_articles(priority); CREATE INDEX IF NOT EXISTS idx_news_articles_notified ON news_articles(notified); CREATE INDEX IF NOT EXISTS idx_news_articles_is_active ON news_articles(is_active); CREATE INDEX IF NOT EXISTS idx_news_articles_created_at ON news_articles(created_at); """ def migrate_create_news_table(): """创建 news_articles 表""" # 数据库路径 db_path = Path(__file__).parent.parent / "backend" / "stock_agent.db" if not db_path.exists(): print(f"❌ 数据库文件不存在: {db_path}") return False try: # 连接数据库 conn = sqlite3.connect(str(db_path)) cursor = conn.cursor() # 检查表是否已存在 cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='news_articles'") if cursor.fetchone(): print("✅ news_articles 表已存在,无需迁移") conn.close() return True # 创建表 print(f"📝 正在创建 news_articles 表到 {db_path}...") # 执行 SQL for sql_statement in CREATE_TABLE_SQL.split(';'): sql_statement = sql_statement.strip() if sql_statement: cursor.execute(sql_statement) conn.commit() # 验证 cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='news_articles'") if cursor.fetchone(): print("✅ news_articles 表创建成功") # 显示索引 cursor.execute("SELECT name FROM sqlite_master WHERE type='index' AND name LIKE 'idx_news_articles%'") indexes = cursor.fetchall() print(f"✅ 创建了 {len(indexes)} 个索引") conn.close() return True else: print("❌ 表创建失败") conn.close() return False except Exception as e: print(f"❌ 迁移失败: {e}") import traceback traceback.print_exc() return False if __name__ == "__main__": print("=" * 60) print("数据库迁移:创建 news_articles 表") print("=" * 60) success = migrate_create_news_table() if success: print("\n✅ 迁移完成!") print("\n请重启服务以使更改生效:") print(" pm2 restart stock-agent") else: print("\n❌ 迁移失败!") print("\n如果自动迁移失败,可以参考 scripts/schema_news.sql 手动执行 SQL")