Spaces:
Paused
Paused
File size: 5,059 Bytes
9d7ddb9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | #!/usr/bin/env python3
"""
存储后端数据迁移脚本
用法:
python scripts/migrate_storage.py --from json --to postgres
python scripts/migrate_storage.py --from postgres --to git
python scripts/migrate_storage.py --export accounts.json
python scripts/migrate_storage.py --import accounts.json
"""
import argparse
import json
import os
import sys
from pathlib import Path
# 添加项目根目录到 Python 路径
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
DATA_DIR = Path(__file__).resolve().parents[1] / "data"
from services.storage.factory import create_storage_backend
def export_to_json(output_file: str):
"""导出当前存储后端的数据到 JSON 文件"""
print(f"[migrate] Exporting data to {output_file}")
DATA_DIR.mkdir(parents=True, exist_ok=True)
storage = create_storage_backend(DATA_DIR)
accounts = storage.load_accounts()
output_path = Path(output_file)
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(
json.dumps(accounts, ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
print(f"[migrate] Exported {len(accounts)} accounts to {output_file}")
def import_from_json(input_file: str):
"""从 JSON 文件导入数据到当前存储后端"""
print(f"[migrate] Importing data from {input_file}")
DATA_DIR.mkdir(parents=True, exist_ok=True)
input_path = Path(input_file)
if not input_path.exists():
print(f"[migrate] Error: File not found: {input_file}")
sys.exit(1)
try:
accounts = json.loads(input_path.read_text(encoding="utf-8"))
if not isinstance(accounts, list):
print(f"[migrate] Error: Invalid JSON format, expected array")
sys.exit(1)
except json.JSONDecodeError as e:
print(f"[migrate] Error: Invalid JSON: {e}")
sys.exit(1)
storage = create_storage_backend(DATA_DIR)
storage.save_accounts(accounts)
print(f"[migrate] Imported {len(accounts)} accounts")
def migrate_data(from_backend: str, to_backend: str):
"""从一个存储后端迁移到另一个"""
print(f"[migrate] Migrating from {from_backend} to {to_backend}")
DATA_DIR.mkdir(parents=True, exist_ok=True)
# 保存原始环境变量
original_backend = os.environ.get("STORAGE_BACKEND")
try:
# 从源后端读取数据
os.environ["STORAGE_BACKEND"] = from_backend
from_storage = create_storage_backend(DATA_DIR)
accounts = from_storage.load_accounts()
print(f"[migrate] Loaded {len(accounts)} accounts from {from_backend}")
# 写入目标后端
os.environ["STORAGE_BACKEND"] = to_backend
to_storage = create_storage_backend(DATA_DIR)
to_storage.save_accounts(accounts)
print(f"[migrate] Saved {len(accounts)} accounts to {to_backend}")
print(f"[migrate] Migration completed successfully!")
finally:
# 恢复原始环境变量
if original_backend:
os.environ["STORAGE_BACKEND"] = original_backend
elif "STORAGE_BACKEND" in os.environ:
del os.environ["STORAGE_BACKEND"]
def main():
parser = argparse.ArgumentParser(
description="ChatGPT2API 存储后端数据迁移工具",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
示例:
# 从 JSON 迁移到 PostgreSQL
python scripts/migrate_storage.py --from json --to postgres
# 从 PostgreSQL 迁移到 Git
python scripts/migrate_storage.py --from postgres --to git
# 导出当前数据到 JSON 文件
python scripts/migrate_storage.py --export backup.json
# 从 JSON 文件导入数据
python scripts/migrate_storage.py --import backup.json
环境变量:
STORAGE_BACKEND - 存储后端类型 (json, sqlite, postgres, git)
DATABASE_URL - 数据库连接字符串
GIT_REPO_URL - Git 仓库地址
GIT_TOKEN - Git 访问令牌
"""
)
parser.add_argument(
"--from",
dest="from_backend",
choices=["json", "sqlite", "postgres", "git"],
help="源存储后端",
)
parser.add_argument(
"--to",
dest="to_backend",
choices=["json", "sqlite", "postgres", "git"],
help="目标存储后端",
)
parser.add_argument(
"--export",
dest="export_file",
metavar="FILE",
help="导出数据到 JSON 文件",
)
parser.add_argument(
"--import",
dest="import_file",
metavar="FILE",
help="从 JSON 文件导入数据",
)
args = parser.parse_args()
# 检查参数
if args.from_backend and args.to_backend:
migrate_data(args.from_backend, args.to_backend)
elif args.export_file:
export_to_json(args.export_file)
elif args.import_file:
import_from_json(args.import_file)
else:
parser.print_help()
sys.exit(1)
if __name__ == "__main__":
main()
|