chatgpt2api / scripts /migrate_storage.py
tx1538's picture
Upload 179 files
9d7ddb9 verified
Raw
History Blame
5.06 kB
#!/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()