add banbanmini backend
This commit is contained in:
92
talkingq-url/scripts/db_management.py
Normal file
92
talkingq-url/scripts/db_management.py
Normal file
@@ -0,0 +1,92 @@
|
||||
import os
|
||||
import sys
|
||||
import asyncio
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from scripts.backup_db import backup_database, list_backups, cleanup_old_backups, BACKUP_DIR
|
||||
from scripts.restore_db import restore_database, interactive_restore
|
||||
from scripts.cleanup_db import cleanup_database, remove_orphaned_records
|
||||
|
||||
async def main():
|
||||
parser = argparse.ArgumentParser(description='数据库备份和恢复工具')
|
||||
subparsers = parser.add_subparsers(dest='command', help='子命令')
|
||||
|
||||
backup_parser = subparsers.add_parser('backup', help='备份数据库')
|
||||
backup_parser.add_argument('--name', type=str, help='备份名称,不含扩展名')
|
||||
backup_parser.add_argument('--no-compress', action='store_true', help='不压缩备份文件')
|
||||
backup_parser.add_argument('--keep', type=int, default=10, help='保留的备份数量')
|
||||
|
||||
restore_parser = subparsers.add_parser('restore', help='恢复数据库')
|
||||
restore_parser.add_argument('--file', type=str, help='要恢复的备份文件')
|
||||
|
||||
list_parser = subparsers.add_parser('list', help='列出所有备份')
|
||||
|
||||
cleanup_parser = subparsers.add_parser('cleanup', help='清理旧备份')
|
||||
cleanup_parser.add_argument('--keep', type=int, default=10, help='保留的备份数量')
|
||||
|
||||
clean_db_parser = subparsers.add_parser('clean-db', help='清理数据库中未使用的表和字段')
|
||||
clean_db_parser.add_argument('--execute', action='store_true', help='执行实际清理(不使用此选项则只进行模拟运行)')
|
||||
clean_db_parser.add_argument('--orphaned', action='store_true', help='仅清理孤立记录')
|
||||
clean_db_parser.add_argument('--schema', action='store_true', help='仅清理未使用的表和字段')
|
||||
clean_db_parser.add_argument('--backup-first', action='store_true', help='清理前先进行备份')
|
||||
clean_db_parser.add_argument('--drop-tables', type=str, help='指定要删除的表,用逗号分隔')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == 'backup':
|
||||
await backup_database(args.name, not args.no_compress if hasattr(args, 'no_compress') else True)
|
||||
await cleanup_old_backups(args.keep if hasattr(args, 'keep') else 10)
|
||||
elif args.command == 'restore':
|
||||
if args.file:
|
||||
await restore_database(args.file)
|
||||
else:
|
||||
await interactive_restore()
|
||||
elif args.command == 'list':
|
||||
backups = await list_backups()
|
||||
if backups:
|
||||
print("\n可用的备份文件:")
|
||||
for backup in backups:
|
||||
file_path = os.path.join(BACKUP_DIR, backup)
|
||||
size = os.path.getsize(file_path) / (1024 * 1024) # 转换为MB
|
||||
print(f"{backup} ({size:.2f} MB)")
|
||||
else:
|
||||
print("没有找到可用的备份")
|
||||
elif args.command == 'cleanup':
|
||||
keep = args.keep if hasattr(args, 'keep') else 10
|
||||
await cleanup_old_backups(keep)
|
||||
elif args.command == 'clean-db':
|
||||
dry_run = not args.execute
|
||||
|
||||
if args.backup_first:
|
||||
print("清理前进行数据库备份...")
|
||||
await backup_database(f"pre_cleanup_{int(asyncio.get_event_loop().time())}", True)
|
||||
|
||||
if args.drop_tables:
|
||||
from scripts.cleanup_db import get_mysql_connection, drop_specific_tables
|
||||
conn = await get_mysql_connection()
|
||||
if conn:
|
||||
try:
|
||||
tables_to_drop = [t.strip() for t in args.drop_tables.split(',')]
|
||||
await drop_specific_tables(conn, tables_to_drop, dry_run)
|
||||
finally:
|
||||
conn.close()
|
||||
else:
|
||||
if not args.orphaned:
|
||||
print("\n分析数据库架构...")
|
||||
await cleanup_database(dry_run)
|
||||
|
||||
if not args.schema:
|
||||
print("\n检查孤立记录...")
|
||||
await remove_orphaned_records(dry_run)
|
||||
|
||||
if dry_run:
|
||||
print("\n这是一次模拟运行,没有执行任何实际更改。")
|
||||
print("要执行实际的清理操作,请使用 --execute 选项。")
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user