feat: 添加热点股追踪数据导出/导入脚本
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# 热点股追踪数据导出/导入工具
|
||||
|
||||
## 功能说明
|
||||
|
||||
本工具用于导出和导入热点股追踪的历史数据,包括:
|
||||
- 每日题材涨幅前20
|
||||
- 每日核心股票(覆盖多个题材的股票)
|
||||
- 每日核心股票与题材的关联关系
|
||||
|
||||
## 快速使用(Docker环境)
|
||||
|
||||
### 1. 导出8月20日的数据
|
||||
|
||||
```bash
|
||||
./scripts/docker_hotspot.sh export 2026-08-20
|
||||
```
|
||||
|
||||
### 2. 导入数据
|
||||
|
||||
```bash
|
||||
# 导入数据到容器
|
||||
./scripts/docker_hotspot.sh import hotspot_2026-08-20.json
|
||||
```
|
||||
|
||||
### 3. 查看数据库中的日期
|
||||
|
||||
```bash
|
||||
./scripts/docker_hotspot.sh list
|
||||
```
|
||||
|
||||
### 4. 备份整个数据库
|
||||
|
||||
```bash
|
||||
./scripts/docker_hotspot.sh backup
|
||||
```
|
||||
|
||||
### 5. 进入Python shell
|
||||
|
||||
```bash
|
||||
./scripts/docker_hotspot.sh shell
|
||||
```
|
||||
|
||||
## 本地开发环境
|
||||
|
||||
如果在本地开发环境中,可以使用以下命令:
|
||||
|
||||
```bash
|
||||
# 导出数据
|
||||
python3 scripts/export_hotspot_data.py export --date 2026-08-20
|
||||
|
||||
# 导入数据
|
||||
python3 scripts/export_hotspot_data.py import --file hotspot_2026-08-20.json
|
||||
|
||||
# 列出日期
|
||||
python3 scripts/export_hotspot_data.py list
|
||||
```
|
||||
|
||||
## 文件说明
|
||||
|
||||
### Docker脚本 (`docker_hotspot.sh`)
|
||||
|
||||
- `export [日期]`: 从容器导出数据(默认8月20日)
|
||||
- `import <文件>`: 导入数据文件到容器
|
||||
- `list`: 列出所有日期
|
||||
- `backup`: 备份整个数据库
|
||||
- `shell`: 进入容器的Python shell
|
||||
|
||||
### Python脚本 (`export_hotspot_data.py`)
|
||||
|
||||
- `export --date YYYY-MM-DD`: 导出指定日期的数据
|
||||
- `import --file <文件路径>`: 导入数据文件
|
||||
- `list`: 列出数据库中所有有数据的日期
|
||||
|
||||
### Shell脚本 (`hotspot_backup.sh`)
|
||||
|
||||
- `export [日期]`: 导出数据(默认8月20日)
|
||||
- `import <文件>`: 导入数据文件
|
||||
- `list`: 列出所有日期
|
||||
- `backup`: 备份整个数据库
|
||||
|
||||
## 数据格式
|
||||
|
||||
导出的JSON文件包含以下字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"trade_date": "2026-08-11",
|
||||
"themes": [...], // 题材数据
|
||||
"core_stocks": [...], // 核心股票数据
|
||||
"stock_themes": [...], // 股票-题材关联
|
||||
"stats": {
|
||||
"theme_count": 20,
|
||||
"core_stock_count": 193,
|
||||
"stock_theme_count": 1205
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **容器运行**:使用Docker脚本前,请确保容器正在运行
|
||||
2. **幂等性**:导入时使用 `INSERT OR IGNORE`,重复导入不会产生重复数据
|
||||
3. **数据完整性**:导入前会检查目标日期是否已有数据
|
||||
4. **备份建议**:导入前建议先备份数据库
|
||||
5. **日期格式**:日期格式必须为 `YYYY-MM-DD`(如 `2026-08-20`)
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 容器未运行怎么办?
|
||||
|
||||
A: 启动容器:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Q: 如何查看容器是否运行?
|
||||
|
||||
A: 运行以下命令:
|
||||
|
||||
```bash
|
||||
docker ps | grep auv
|
||||
```
|
||||
|
||||
### Q: 如何手动采集8月20日的数据?
|
||||
|
||||
A: 在容器内运行:
|
||||
|
||||
```bash
|
||||
docker exec -it auv python3 -c "
|
||||
import asyncio
|
||||
from services.daily_collector import collect_daily
|
||||
asyncio.run(collect_daily('2026-08-20'))
|
||||
"
|
||||
```
|
||||
|
||||
### Q: 如何查看数据库中的日期?
|
||||
|
||||
A: 运行 `./scripts/docker_hotspot.sh list`
|
||||
|
||||
### Q: 如何备份数据库?
|
||||
|
||||
A: 运行 `./scripts/docker_hotspot.sh backup`
|
||||
|
||||
### Q: 导入时出现错误怎么办?
|
||||
|
||||
A: 检查JSON文件格式是否正确,确保包含必要的字段。可以使用以下命令验证JSON:
|
||||
|
||||
```bash
|
||||
python3 -m json.tool hotspot_2026-08-20.json
|
||||
```
|
||||
Executable
+236
@@ -0,0 +1,236 @@
|
||||
#!/bin/bash
|
||||
# 从Docker容器导出热点股数据
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
CONTAINER_NAME="auv"
|
||||
DB_PATH="/app/backend/data/stock_data.db"
|
||||
|
||||
# 检查容器是否运行
|
||||
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||
echo -e "${RED}❌ 容器 ${CONTAINER_NAME} 未运行${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查数据库是否存在
|
||||
if ! docker exec "$CONTAINER_NAME" test -f "$DB_PATH"; then
|
||||
echo -e "${RED}❌ 数据库文件不存在:$DB_PATH${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 显示帮助
|
||||
show_help() {
|
||||
echo "用法:"
|
||||
echo " $0 export [日期] - 导出指定日期的数据(默认:2026-08-20)"
|
||||
echo " $0 import <文件> - 导入数据文件到容器"
|
||||
echo " $0 list - 列出所有有数据的日期"
|
||||
echo " $0 backup - 备份整个数据库"
|
||||
echo " $0 shell - 进入容器的Python shell"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 export 2026-08-20"
|
||||
echo " $0 import hotspot_2026-08-20.json"
|
||||
echo " $0 backup"
|
||||
}
|
||||
|
||||
# 导出数据
|
||||
export_data() {
|
||||
local date="${1:-2026-08-20}"
|
||||
local output_file="hotspot_${date}.json"
|
||||
|
||||
echo -e "${YELLOW}📤 从容器导出 $date 的热点股数据...${NC}"
|
||||
|
||||
# 在容器内执行导出命令
|
||||
docker exec "$CONTAINER_NAME" python3 -c "
|
||||
import sys
|
||||
sys.path.insert(0, '/app')
|
||||
from database import get_connection, dict_from_row
|
||||
import json
|
||||
|
||||
date = '$date'
|
||||
conn = get_connection()
|
||||
try:
|
||||
themes = conn.execute('SELECT * FROM daily_top_themes WHERE trade_date = ? ORDER BY rank ASC', (date,)).fetchall()
|
||||
core_stocks = conn.execute('SELECT * FROM daily_core_stocks WHERE trade_date = ? ORDER BY rank ASC', (date,)).fetchall()
|
||||
stock_themes = conn.execute('SELECT * FROM daily_core_stock_themes WHERE trade_date = ?', (date,)).fetchall()
|
||||
|
||||
data = {
|
||||
'version': '1.0',
|
||||
'trade_date': date,
|
||||
'themes': [dict_from_row(r) for r in themes],
|
||||
'core_stocks': [dict_from_row(r) for r in core_stocks],
|
||||
'stock_themes': [dict_from_row(r) for r in stock_themes],
|
||||
}
|
||||
data['stats'] = {
|
||||
'theme_count': len(data['themes']),
|
||||
'core_stock_count': len(data['core_stocks']),
|
||||
'stock_theme_count': len(data['stock_themes']),
|
||||
}
|
||||
|
||||
print(json.dumps(data, ensure_ascii=False, indent=2))
|
||||
finally:
|
||||
conn.close()
|
||||
" > "$output_file"
|
||||
|
||||
if [ -f "$output_file" ]; then
|
||||
echo -e "${GREEN}✅ 导出完成:$output_file${NC}"
|
||||
echo "文件大小:$(du -h "$output_file" | cut -f1)"
|
||||
else
|
||||
echo -e "${RED}❌ 导出失败${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 导入数据
|
||||
import_data() {
|
||||
local file="$1"
|
||||
|
||||
if [ -z "$file" ]; then
|
||||
echo -e "${RED}❌ 请指定要导入的文件${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$file" ]; then
|
||||
echo -e "${RED}❌ 文件不存在:$file${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}📥 导入数据到容器:$file${NC}"
|
||||
|
||||
# 复制文件到容器
|
||||
docker cp "$file" "$CONTAINER_NAME:/tmp/import_data.json"
|
||||
|
||||
# 在容器内执行导入
|
||||
docker exec "$CONTAINER_NAME" python3 -c "
|
||||
import sys
|
||||
import json
|
||||
sys.path.insert(0, '/app')
|
||||
from database import get_connection
|
||||
|
||||
with open('/tmp/import_data.json', 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
date = data['trade_date']
|
||||
print(f'📅 导入日期:{date}')
|
||||
print(f' 题材数量:{len(data[\"themes\"])}')
|
||||
print(f' 核心股票:{len(data[\"core_stocks\"])}')
|
||||
print(f' 股票-题材关联:{len(data[\"stock_themes\"])}')
|
||||
|
||||
conn = get_connection()
|
||||
try:
|
||||
for item in data['themes']:
|
||||
item.pop('id', None)
|
||||
item.pop('created_at', None)
|
||||
conn.execute(
|
||||
'INSERT OR IGNORE INTO daily_top_themes (trade_date, theme_code, theme_name, bf3, hot_rank, rank) VALUES (?,?,?,?,?,?)',
|
||||
(item['trade_date'], item['theme_code'], item['theme_name'], item['bf3'], item['hot_rank'], item['rank']),
|
||||
)
|
||||
|
||||
for item in data['core_stocks']:
|
||||
item.pop('id', None)
|
||||
item.pop('created_at', None)
|
||||
conn.execute(
|
||||
'INSERT OR IGNORE INTO daily_core_stocks (trade_date, stock_code, stock_name, f3, cover_count, rank) VALUES (?,?,?,?,?,?)',
|
||||
(item['trade_date'], item['stock_code'], item['stock_name'], item['f3'], item['cover_count'], item['rank']),
|
||||
)
|
||||
|
||||
for item in data['stock_themes']:
|
||||
item.pop('id', None)
|
||||
item.pop('created_at', None)
|
||||
conn.execute(
|
||||
'INSERT OR IGNORE INTO daily_core_stock_themes (trade_date, stock_code, theme_code, theme_name) VALUES (?,?,?,?)',
|
||||
(item['trade_date'], item['stock_code'], item['theme_code'], item['theme_name']),
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
print(f'\\n✅ 导入成功:{date}')
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
print(f'\\n❌ 导入失败:{e}')
|
||||
finally:
|
||||
conn.close()
|
||||
"
|
||||
}
|
||||
|
||||
# 列出日期
|
||||
list_dates() {
|
||||
echo -e "${YELLOW}📅 列出容器中的日期...${NC}"
|
||||
docker exec "$CONTAINER_NAME" python3 -c "
|
||||
import sys
|
||||
sys.path.insert(0, '/app')
|
||||
from database import get_connection
|
||||
|
||||
conn = get_connection()
|
||||
try:
|
||||
rows = conn.execute('SELECT DISTINCT trade_date FROM daily_core_stocks ORDER BY trade_date DESC').fetchall()
|
||||
if rows:
|
||||
print('📅 数据库中的日期:')
|
||||
for row in rows:
|
||||
print(f' {row[\"trade_date\"]}')
|
||||
else:
|
||||
print('📭 数据库中暂无数据')
|
||||
finally:
|
||||
conn.close()
|
||||
"
|
||||
}
|
||||
|
||||
# 备份数据库
|
||||
backup_database() {
|
||||
local timestamp=$(date +%Y%m%d_%H%M%S)
|
||||
local backup_file="stock_data_${timestamp}.db"
|
||||
|
||||
echo -e "${YELLOW}💾 备份数据库...${NC}"
|
||||
docker cp "$CONTAINER_NAME:$DB_PATH" "$backup_file"
|
||||
|
||||
if [ -f "$backup_file" ]; then
|
||||
echo -e "${GREEN}✅ 备份完成:$backup_file${NC}"
|
||||
echo "文件大小:$(du -h "$backup_file" | cut -f1)"
|
||||
else
|
||||
echo -e "${RED}❌ 备份失败${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 进入Python shell
|
||||
enter_shell() {
|
||||
echo -e "${YELLOW}🐍 进入容器Python shell...${NC}"
|
||||
docker exec -it "$CONTAINER_NAME" python3 -c "
|
||||
import sys
|
||||
sys.path.insert(0, '/app')
|
||||
from database import get_connection
|
||||
print('Python shell 已启动')
|
||||
print('可用变量:')
|
||||
print(' conn - 数据库连接')
|
||||
print(' get_connection - 获取新连接函数')
|
||||
print()
|
||||
conn = get_connection()
|
||||
"
|
||||
}
|
||||
|
||||
# 主逻辑
|
||||
case "${1:-help}" in
|
||||
export)
|
||||
export_data "$2"
|
||||
;;
|
||||
import)
|
||||
import_data "$2"
|
||||
;;
|
||||
list)
|
||||
list_dates
|
||||
;;
|
||||
backup)
|
||||
backup_database
|
||||
;;
|
||||
shell)
|
||||
enter_shell
|
||||
;;
|
||||
*)
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
Executable
+213
@@ -0,0 +1,213 @@
|
||||
#!/usr/bin/env python3
|
||||
"""热点股追踪数据导出/导入脚本
|
||||
|
||||
用法:
|
||||
导出8月20日数据:
|
||||
python scripts/export_hotspot_data.py export --date 2026-08-20
|
||||
|
||||
导入数据:
|
||||
python scripts/export_hotspot_data.py import --file hotspot_2026-08-20.json
|
||||
|
||||
查看数据库中有哪些日期的数据:
|
||||
python scripts/export_hotspot_data.py list
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
# 添加项目路径
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "backend"))
|
||||
|
||||
from database import get_connection, dict_from_row
|
||||
|
||||
|
||||
def export_data(date: str, output_file: Optional[str] = None) -> dict:
|
||||
"""导出指定日期的热点股追踪数据"""
|
||||
conn = get_connection()
|
||||
try:
|
||||
# 1. 导出每日题材前20
|
||||
themes = conn.execute(
|
||||
"SELECT * FROM daily_top_themes WHERE trade_date = ? ORDER BY rank ASC",
|
||||
(date,),
|
||||
).fetchall()
|
||||
|
||||
# 2. 导出每日核心股票
|
||||
core_stocks = conn.execute(
|
||||
"SELECT * FROM daily_core_stocks WHERE trade_date = ? ORDER BY rank ASC",
|
||||
(date,),
|
||||
).fetchall()
|
||||
|
||||
# 3. 导出每日核心股票与题材的关联
|
||||
stock_themes = conn.execute(
|
||||
"SELECT * FROM daily_core_stock_themes WHERE trade_date = ?",
|
||||
(date,),
|
||||
).fetchall()
|
||||
|
||||
data = {
|
||||
"version": "1.0",
|
||||
"export_time": datetime.now().isoformat(),
|
||||
"trade_date": date,
|
||||
"themes": [dict_from_row(r) for r in themes],
|
||||
"core_stocks": [dict_from_row(r) for r in core_stocks],
|
||||
"stock_themes": [dict_from_row(r) for r in stock_themes],
|
||||
}
|
||||
|
||||
# 统计信息
|
||||
data["stats"] = {
|
||||
"theme_count": len(data["themes"]),
|
||||
"core_stock_count": len(data["core_stocks"]),
|
||||
"stock_theme_count": len(data["stock_themes"]),
|
||||
}
|
||||
|
||||
# 保存到文件
|
||||
if output_file is None:
|
||||
output_file = f"hotspot_{date}.json"
|
||||
|
||||
with open(output_file, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
|
||||
print(f"✅ 导出成功:{output_file}")
|
||||
print(f" 题材数量:{data['stats']['theme_count']}")
|
||||
print(f" 核心股票:{data['stats']['core_stock_count']}")
|
||||
print(f" 股票-题材关联:{data['stats']['stock_theme_count']}")
|
||||
|
||||
return data
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def import_data(input_file: str, dry_run: bool = False) -> bool:
|
||||
"""导入热点股追踪数据"""
|
||||
if not os.path.exists(input_file):
|
||||
print(f"❌ 文件不存在:{input_file}")
|
||||
return False
|
||||
|
||||
with open(input_file, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
# 验证数据格式
|
||||
required_keys = ["version", "trade_date", "themes", "core_stocks", "stock_themes"]
|
||||
if not all(k in data for k in required_keys):
|
||||
print("❌ 数据格式错误:缺少必要字段")
|
||||
return False
|
||||
|
||||
date = data["trade_date"]
|
||||
print(f"📅 导入日期:{date}")
|
||||
print(f" 题材数量:{len(data['themes'])}")
|
||||
print(f" 核心股票:{len(data['core_stocks'])}")
|
||||
print(f" 股票-题材关联:{len(data['stock_themes'])}")
|
||||
|
||||
if dry_run:
|
||||
print("\n🔍 试运行模式,不写入数据库")
|
||||
return True
|
||||
|
||||
# 检查是否已存在
|
||||
conn = get_connection()
|
||||
try:
|
||||
existing = conn.execute(
|
||||
"SELECT 1 FROM daily_core_stocks WHERE trade_date = ? LIMIT 1",
|
||||
(date,),
|
||||
).fetchone()
|
||||
|
||||
if existing:
|
||||
print(f"\n⚠️ {date} 的数据已存在,将跳过重复数据(使用 INSERT OR IGNORE)")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
# 写入数据库
|
||||
conn = get_connection()
|
||||
try:
|
||||
# 导入每日题材前20
|
||||
for item in data["themes"]:
|
||||
# 移除自动生成的id和created_at
|
||||
item.pop("id", None)
|
||||
item.pop("created_at", None)
|
||||
conn.execute(
|
||||
"INSERT OR IGNORE INTO daily_top_themes (trade_date, theme_code, theme_name, bf3, hot_rank, rank) VALUES (?,?,?,?,?,?)",
|
||||
(item["trade_date"], item["theme_code"], item["theme_name"], item["bf3"], item["hot_rank"], item["rank"]),
|
||||
)
|
||||
|
||||
# 导入每日核心股票
|
||||
for item in data["core_stocks"]:
|
||||
# 移除自动生成的id和created_at
|
||||
item.pop("id", None)
|
||||
item.pop("created_at", None)
|
||||
conn.execute(
|
||||
"INSERT OR IGNORE INTO daily_core_stocks (trade_date, stock_code, stock_name, f3, cover_count, rank) VALUES (?,?,?,?,?,?)",
|
||||
(item["trade_date"], item["stock_code"], item["stock_name"], item["f3"], item["cover_count"], item["rank"]),
|
||||
)
|
||||
|
||||
# 导入每日核心股票与题材的关联
|
||||
for item in data["stock_themes"]:
|
||||
# 移除自动生成的id和created_at
|
||||
item.pop("id", None)
|
||||
item.pop("created_at", None)
|
||||
conn.execute(
|
||||
"INSERT OR IGNORE INTO daily_core_stock_themes (trade_date, stock_code, theme_code, theme_name) VALUES (?,?,?,?)",
|
||||
(item["trade_date"], item["stock_code"], item["theme_code"], item["theme_name"]),
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
print(f"\n✅ 导入成功:{date}")
|
||||
return True
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
print(f"\n❌ 导入失败:{e}")
|
||||
return False
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def list_dates() -> list[str]:
|
||||
"""列出数据库中所有有数据的日期"""
|
||||
conn = get_connection()
|
||||
try:
|
||||
rows = conn.execute(
|
||||
"SELECT DISTINCT trade_date FROM daily_core_stocks ORDER BY trade_date DESC"
|
||||
).fetchall()
|
||||
return [row["trade_date"] for row in rows]
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="热点股追踪数据导出/导入工具")
|
||||
subparsers = parser.add_subparsers(dest="command", help="可用命令")
|
||||
|
||||
# 导出命令
|
||||
export_parser = subparsers.add_parser("export", help="导出数据")
|
||||
export_parser.add_argument("--date", required=True, help="交易日期 (YYYY-MM-DD)")
|
||||
export_parser.add_argument("--output", "-o", help="输出文件路径")
|
||||
|
||||
# 导入命令
|
||||
import_parser = subparsers.add_parser("import", help="导入数据")
|
||||
import_parser.add_argument("--file", "-f", required=True, help="输入文件路径")
|
||||
import_parser.add_argument("--dry-run", action="store_true", help="试运行,不写入数据库")
|
||||
|
||||
# 列表命令
|
||||
subparsers.add_parser("list", help="列出所有有数据的日期")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == "export":
|
||||
export_data(args.date, args.output)
|
||||
elif args.command == "import":
|
||||
import_data(args.file, args.dry_run)
|
||||
elif args.command == "list":
|
||||
dates = list_dates()
|
||||
if dates:
|
||||
print("📅 数据库中的日期:")
|
||||
for d in dates:
|
||||
print(f" {d}")
|
||||
else:
|
||||
print("📭 数据库中暂无数据")
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Executable
+110
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
# 热点股追踪数据导出/导入快捷脚本
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
PYTHON_SCRIPT="$SCRIPT_DIR/export_hotspot_data.py"
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
show_help() {
|
||||
echo "用法:"
|
||||
echo " $0 export [日期] - 导出指定日期的数据(默认:2026-08-20)"
|
||||
echo " $0 import <文件> - 导入数据文件"
|
||||
echo " $0 list - 列出所有有数据的日期"
|
||||
echo " $0 backup - 备份整个数据库"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 export 2026-08-20"
|
||||
echo " $0 import hotspot_2026-08-20.json"
|
||||
echo " $0 backup"
|
||||
}
|
||||
|
||||
export_data() {
|
||||
local date="${1:-2026-08-20}"
|
||||
local output_file="hotspot_${date}.json"
|
||||
|
||||
echo -e "${YELLOW}📤 导出 $date 的热点股数据...${NC}"
|
||||
python3 "$PYTHON_SCRIPT" export --date "$date" --output "$output_file"
|
||||
|
||||
if [ -f "$output_file" ]; then
|
||||
echo -e "${GREEN}✅ 导出完成:$output_file${NC}"
|
||||
echo "文件大小:$(du -h "$output_file" | cut -f1)"
|
||||
else
|
||||
echo -e "${RED}❌ 导出失败${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
import_data() {
|
||||
local file="$1"
|
||||
|
||||
if [ -z "$file" ]; then
|
||||
echo -e "${RED}❌ 请指定要导入的文件${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$file" ]; then
|
||||
echo -e "${RED}❌ 文件不存在:$file${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}📥 导入数据:$file${NC}"
|
||||
python3 "$PYTHON_SCRIPT" import --file "$file"
|
||||
}
|
||||
|
||||
list_dates() {
|
||||
echo -e "${YELLOW}📅 列出数据库中的日期...${NC}"
|
||||
python3 "$PYTHON_SCRIPT" list
|
||||
}
|
||||
|
||||
backup_database() {
|
||||
local db_path="$PROJECT_DIR/backend/data/stock_data.db"
|
||||
local backup_dir="$PROJECT_DIR/backups"
|
||||
local timestamp=$(date +%Y%m%d_%H%M%S)
|
||||
local backup_file="$backup_dir/stock_data_${timestamp}.db"
|
||||
|
||||
if [ ! -f "$db_path" ]; then
|
||||
echo -e "${RED}❌ 数据库文件不存在:$db_path${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p "$backup_dir"
|
||||
|
||||
# 复制数据库
|
||||
cp "$db_path" "$backup_file"
|
||||
|
||||
if [ -f "$backup_file" ]; then
|
||||
echo -e "${GREEN}✅ 数据库备份完成:$backup_file${NC}"
|
||||
echo "文件大小:$(du -h "$backup_file" | cut -f1)"
|
||||
else
|
||||
echo -e "${RED}❌ 备份失败${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 主逻辑
|
||||
case "${1:-help}" in
|
||||
export)
|
||||
export_data "$2"
|
||||
;;
|
||||
import)
|
||||
import_data "$2"
|
||||
;;
|
||||
list)
|
||||
list_dates
|
||||
;;
|
||||
backup)
|
||||
backup_database
|
||||
;;
|
||||
*)
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user