import subprocess import os import datetime import sys from db.mongo_manager import MONGO_DB_URL # ================= 配置区域 ================= # 数据库连接信息 MONGO_HOST = "mongo.lpaconsulting.fr" MONGO_PORT = "27017" MONGO_DB_NAME = "appointment" # 你要备份/恢复的数据库名 # Get MongoDB credentials from environment variables MONGO_USER = os.getenv( "MONGO_USER", "appointment" ) # Default to 'appointment' if not set MONGO_PASS = os.getenv("MONGO_PASS", "Rdv@2022") # Default to 'Rdv@2022' if not set # 备份存放的根目录 BACKUP_DIR_ROOT = "./mongo_backups" # =========================================== def get_auth_args(): """构建认证参数列表""" args = [] if MONGO_USER and MONGO_PASS: args.extend( [ "--username", MONGO_USER, "--password", MONGO_PASS, "--authenticationDatabase", "appointment", ] ) return args def backup_mongo(): """执行备份操作""" # 1. 创建带有时间戳的备份文件夹 timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") backup_path = os.path.join(BACKUP_DIR_ROOT, timestamp) if not os.path.exists(backup_path): os.makedirs(backup_path) print(f"[*] 开始备份数据库: {MONGO_DB_NAME} 到 {backup_path} ...") # 2. 构建 mongodump 命令 # 命令格式: mongodump --host --port --db --out [auth] cmd = [ "mongodump", "--host", MONGO_HOST, "--port", MONGO_PORT, "--db", MONGO_DB_NAME, "--out", backup_path, ] # 添加认证参数 cmd.extend(get_auth_args()) try: # 3. 执行命令 result = subprocess.run(cmd, check=True, text=True, capture_output=True) print(f"[+] 备份成功!") print(f" 存储路径: {backup_path}") print(f" 日志: {result.stderr}") # mongodump 通常把进度输出到 stderr return backup_path except subprocess.CalledProcessError as e: print(f"[-] 备份失败: {e}") print(f" 错误信息: {e.stderr}") return None def restore_mongo(backup_source_path): """ 执行恢复操作 backup_source_path: 备份文件夹的路径 (例如 ./mongo_backups/2023-10-27_10-00-00) """ # mongodump 的输出结构通常是: backup_dir/db_name/collection.bson # 所以我们需要指向具体的数据库文件夹,或者指向父文件夹并指定 --db target_dir = os.path.join(backup_source_path, MONGO_DB_NAME) if not os.path.exists(target_dir): print( f"[-] 错误: 在路径 {backup_source_path} 下找不到数据库 {MONGO_DB_NAME} 的备份文件。" ) return print(f"[*] 开始恢复数据库: {MONGO_DB_NAME} 从 {target_dir} ...") # 构建 mongorestore 命令 # 命令格式: mongorestore --host --port --db [auth] cmd = [ "mongorestore", "--host", MONGO_HOST, "--port", MONGO_PORT, "--db", MONGO_DB_NAME, "--drop", # 警告:这会在恢复前删除现有集合,确保数据干净。根据需要移除此项。 target_dir, ] cmd.extend(get_auth_args()) try: result = subprocess.run(cmd, check=True, text=True, capture_output=True) print(f"[+] 恢复成功!") print(f" 日志: {result.stderr}") except subprocess.CalledProcessError as e: print(f"[-] 恢复失败: {e}") print(f" 错误信息: {e.stderr}") # ================= 主程序入口 ================= if __name__ == "__main__": print("请选择操作:") print("1. 备份数据库 (Backup)") print("2. 恢复数据库 (Restore)") choice = input("请输入数字 (1/2): ").strip() if choice == "1": backup_mongo() elif choice == "2": # 列出所有备份供用户选择 if not os.path.exists(BACKUP_DIR_ROOT): print("[-] 没有找到备份目录。") else: backups = sorted(os.listdir(BACKUP_DIR_ROOT)) if not backups: print("[-] 目录为空。") else: print("\n可用备份:") for idx, name in enumerate(backups): print(f"{idx + 1}. {name}") try: idx_choice = int(input("\n请选择要恢复的备份编号: ")) - 1 if 0 <= idx_choice < len(backups): selected_backup = os.path.join( BACKUP_DIR_ROOT, backups[idx_choice] ) restore_mongo(selected_backup) else: print("[-] 无效的选择。") except ValueError: print("[-] 请输入数字。") else: print("[-] 无效输入,退出。")