lydgs commited on
Commit
d67c3c1
·
verified ·
1 Parent(s): 4cb8f19

Update scripts/restore_from_dataset.py

Browse files
Files changed (1) hide show
  1. scripts/restore_from_dataset.py +81 -54
scripts/restore_from_dataset.py CHANGED
@@ -2,87 +2,114 @@
2
  import os
3
  import sys
4
  import shutil
 
 
 
 
5
  import datetime
6
  from huggingface_hub import HfApi, login, hf_hub_download
7
 
8
- # ===== 配置 =====
9
- DB_TARGET = "/app/server/data/freeapi.db" # 本地数据库路径
10
- DATASET_REPO = "lydgs/freellm-backup" # 你的数据集名称
11
- BACKUP_PREFIX = "freeapi_backup" # 备份文件前缀
12
- # ================
13
 
14
- def upload_backup(db_path, dataset_repo, backup_prefix):
15
- """上传数据库作为备份,返回是否成功"""
16
- if not os.path.exists(db_path):
17
- print(f"⚠️ 本地数据库不存在: {db_path},无法创建备份")
18
  return False
 
 
 
 
 
19
 
20
- token = os.getenv("HF_TOKEN")
21
- if not token:
22
- print("❌ 环境变量 HF_TOKEN 未设置,无法创建备份")
23
- return False
24
-
25
- timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
26
- backup_name = f"{backup_prefix}_{timestamp}.db"
27
-
28
- login(token=token)
29
- api = HfApi()
30
 
31
- try:
32
- api.upload_file(
33
- path_or_fileobj=db_path,
34
- path_in_repo=backup_name,
35
- repo_id=dataset_repo,
36
- repo_type="dataset"
37
- )
38
- print(f"✅ 初始备份创建成功: {backup_name}")
39
- return True
40
- except Exception as e:
41
- print(f"❌ 创建初始备份失败: {e}")
42
- return False
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  def restore_latest_backup():
45
  token = os.getenv("HF_TOKEN")
46
  if not token:
47
- print("⚠️ 未设置 HF_TOKEN 环境变量,跳过数据库恢复")
48
  return
49
-
50
  login(token=token)
51
  api = HfApi()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
 
53
  try:
54
- # 列出数据集中的所有文件
55
  files = api.list_repo_files(repo_id=DATASET_REPO, repo_type="dataset")
56
- db_files = [f for f in files if f.endswith(".db") and f.startswith(BACKUP_PREFIX)]
57
-
58
  if not db_files:
59
- print("ℹ️ 数据集中没有找到备份文件")
60
- # 如果没有备份,但本地数据库已存在,则主动创建一份备份
61
- if os.path.exists(DB_TARGET):
62
- print("🔄 检测到本地数据库存在,将创建初始备份...")
63
- upload_backup(DB_TARGET, DATASET_REPO, BACKUP_PREFIX)
64
- else:
65
- print("ℹ️ 本地数据库也不存在,跳过恢复")
66
  return
67
-
68
- # 有备份文件:取最新的进行恢复
69
  db_files.sort()
70
- latest = db_files[-1]
71
- print(f"🔄 发现最新备份: {latest},开始下载...")
72
-
73
  downloaded = hf_hub_download(
74
  repo_id=DATASET_REPO,
75
- filename=latest,
76
  repo_type="dataset",
77
  local_dir="/tmp"
78
  )
79
-
80
- # 确保目标目录存在
81
  os.makedirs(os.path.dirname(DB_TARGET), exist_ok=True)
82
-
83
- # 复制到目标位置
84
  shutil.copy(downloaded, DB_TARGET)
85
- print(f"✅ 数据库恢复成功: {DB_TARGET} (来自备份 {latest})")
86
  os.remove(downloaded)
87
  except Exception as e:
88
  print(f"❌ 数据库恢复失败: {e}")
 
2
  import os
3
  import sys
4
  import shutil
5
+ import json
6
+ import sqlite3
7
+ import tarfile
8
+ import tempfile
9
  import datetime
10
  from huggingface_hub import HfApi, login, hf_hub_download
11
 
12
+ DB_TARGET = "/app/server/data/freeapi.db"
13
+ DATASET_REPO = "lydgs/freellm-backup"
14
+ CONFIG_PREFIX = "config_export"
 
 
15
 
16
+ def import_json_to_db(json_dir, db_path):
17
+ """从包含 JSON 文件的目录重建数据库"""
18
+ if not os.path.exists(json_dir):
 
19
  return False
20
+ # 确保数据库所在目录存在
21
+ os.makedirs(os.path.dirname(db_path), exist_ok=True)
22
+ # 如果已有数据库,先删除(避免表冲突)
23
+ if os.path.exists(db_path):
24
+ os.remove(db_path)
25
 
26
+ conn = sqlite3.connect(db_path)
27
+ cursor = conn.cursor()
 
 
 
 
 
 
 
 
28
 
29
+ for json_file in os.listdir(json_dir):
30
+ if not json_file.endswith('.json'):
31
+ continue
32
+ table_name = json_file[:-5]
33
+ with open(os.path.join(json_dir, json_file), 'r', encoding='utf-8') as f:
34
+ data = json.load(f)
35
+ if not data:
36
+ # 空表:至少需要创建表结构。我们假设有列信息?简化处理:跳过或根据第一个 row 创建。
37
+ continue
38
+ # 根据第一行数据创建表(如果表不存在)
39
+ first_row = data[0]
40
+ columns = ', '.join(f'"{col}"' for col in first_row.keys())
41
+ placeholders = ', '.join('?' for _ in first_row)
42
+ # 删除旧表(如果有)
43
+ cursor.execute(f"DROP TABLE IF EXISTS {table_name}")
44
+ cursor.execute(f"CREATE TABLE {table_name} ({columns})")
45
+ # 插入所有行
46
+ for row in data:
47
+ values = list(row.values())
48
+ sql = f"INSERT INTO {table_name} ({', '.join(row.keys())}) VALUES ({placeholders})"
49
+ cursor.execute(sql, values)
50
+ conn.commit()
51
+ conn.close()
52
+ return True
53
 
54
  def restore_latest_backup():
55
  token = os.getenv("HF_TOKEN")
56
  if not token:
57
+ print("⚠️ 未设置 HF_TOKEN,跳过恢复")
58
  return
 
59
  login(token=token)
60
  api = HfApi()
61
+
62
+ # 1. 优先尝试使用 JSON 配置包重建数据库
63
+ try:
64
+ files = api.list_repo_files(repo_id=DATASET_REPO, repo_type="dataset")
65
+ config_files = [f for f in files if f.startswith(CONFIG_PREFIX) and f.endswith('.tar.gz')]
66
+ if config_files:
67
+ config_files.sort(reverse=True) # 最新的排前面
68
+ latest_config = config_files[0]
69
+ print(f"🔄 发现配置包: {latest_config},将用 JSON 重建数据库...")
70
+ # 下载到临时目录
71
+ with tempfile.TemporaryDirectory() as tmpdir:
72
+ downloaded = hf_hub_download(
73
+ repo_id=DATASET_REPO,
74
+ filename=latest_config,
75
+ repo_type="dataset",
76
+ local_dir=tmpdir
77
+ )
78
+ # 解压
79
+ extract_dir = os.path.join(tmpdir, "extract")
80
+ os.makedirs(extract_dir, exist_ok=True)
81
+ with tarfile.open(downloaded, "r:gz") as tar:
82
+ tar.extractall(extract_dir)
83
+ # 导入 JSON 到数据库
84
+ if import_json_to_db(extract_dir, DB_TARGET):
85
+ print(f"✅ 数据库从 JSON 配置重建成功: {DB_TARGET}")
86
+ return
87
+ else:
88
+ print("⚠️ JSON 导入失败,尝试回退到二进制备份...")
89
+ else:
90
+ print("ℹ️ 未找到 JSON 配置包,尝试二进制备份...")
91
+ except Exception as e:
92
+ print(f"⚠️ 处理 JSON 配置包时出错: {e},尝试二进制备份...")
93
 
94
+ # 2. 回退:使用二进制 DB 备份
95
  try:
 
96
  files = api.list_repo_files(repo_id=DATASET_REPO, repo_type="dataset")
97
+ db_files = [f for f in files if f.endswith(".db") and f.startswith("freeapi_backup_")]
 
98
  if not db_files:
99
+ print("ℹ️ 找到任何备份,跳过恢复")
 
 
 
 
 
 
100
  return
 
 
101
  db_files.sort()
102
+ latest_db = db_files[-1]
103
+ print(f"🔄 使用二进制备份恢复: {latest_db}")
 
104
  downloaded = hf_hub_download(
105
  repo_id=DATASET_REPO,
106
+ filename=latest_db,
107
  repo_type="dataset",
108
  local_dir="/tmp"
109
  )
 
 
110
  os.makedirs(os.path.dirname(DB_TARGET), exist_ok=True)
 
 
111
  shutil.copy(downloaded, DB_TARGET)
112
+ print(f"✅ 数据库从二进制备份恢复成功: {DB_TARGET}")
113
  os.remove(downloaded)
114
  except Exception as e:
115
  print(f"❌ 数据库恢复失败: {e}")