migrate_data_to_cache.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #!/usr/bin/env python3
  2. """
  3. 数据目录迁移脚本
  4. 将 data/ 目录迁移到 cache/data/ 目录下,实现统一的缓存管理。
  5. 注意:
  6. - 会保留 data/ 目录中的非缓存文件(如文档、配置等)
  7. - 只移动缓存性质的数据(爬虫数据、分析结果等)
  8. """
  9. import os
  10. import shutil
  11. from pathlib import Path
  12. def migrate_data_to_cache():
  13. """将 data 目录迁移到 cache/data"""
  14. project_root = Path(__file__).parent
  15. old_data_dir = project_root / "data"
  16. new_data_dir = project_root / "cache" / "data"
  17. print("=" * 60)
  18. print("数据目录迁移脚本")
  19. print("=" * 60)
  20. print(f"源目录: {old_data_dir}")
  21. print(f"目标目录: {new_data_dir}")
  22. print()
  23. # 检查源目录是否存在
  24. if not old_data_dir.exists():
  25. print("✓ data/ 目录不存在,无需迁移")
  26. return
  27. # 确保目标目录的父目录存在
  28. new_data_dir.parent.mkdir(parents=True, exist_ok=True)
  29. # 如果目标目录已存在,询问是否覆盖
  30. if new_data_dir.exists():
  31. print(f"⚠️ 目标目录已存在: {new_data_dir}")
  32. response = input("是否继续?这将合并两个目录的内容 (y/n): ")
  33. if response.lower() != 'y':
  34. print("取消迁移")
  35. return
  36. print("开始迁移...")
  37. print()
  38. # 统计信息
  39. total_files = 0
  40. total_dirs = 0
  41. skipped_items = []
  42. # 需要跳过的目录和文件(非缓存数据)
  43. skip_patterns = {
  44. '.git',
  45. '.DS_Store',
  46. '__pycache__',
  47. '*.md', # 文档文件
  48. '*.txt', # 说明文件
  49. 'README*',
  50. }
  51. # 遍历源目录
  52. for item in old_data_dir.iterdir():
  53. item_name = item.name
  54. # 检查是否应该跳过
  55. should_skip = False
  56. for pattern in skip_patterns:
  57. if pattern.startswith('*'):
  58. if item_name.endswith(pattern[1:]):
  59. should_skip = True
  60. break
  61. elif pattern.endswith('*'):
  62. if item_name.startswith(pattern[:-1]):
  63. should_skip = True
  64. break
  65. elif item_name == pattern:
  66. should_skip = True
  67. break
  68. if should_skip:
  69. skipped_items.append(item_name)
  70. print(f"⊘ 跳过: {item_name} (非缓存数据)")
  71. continue
  72. # 目标路径
  73. target = new_data_dir / item_name
  74. try:
  75. if item.is_dir():
  76. # 如果目标已存在,合并;否则直接移动
  77. if target.exists():
  78. print(f"→ 合并目录: {item_name}/")
  79. # 递归复制并删除源
  80. shutil.copytree(item, target, dirs_exist_ok=True)
  81. shutil.rmtree(item)
  82. else:
  83. print(f"→ 移动目录: {item_name}/")
  84. shutil.move(str(item), str(target))
  85. total_dirs += 1
  86. else:
  87. # 文件直接移动
  88. if target.exists():
  89. print(f"→ 覆盖文件: {item_name}")
  90. else:
  91. print(f"→ 移动文件: {item_name}")
  92. shutil.move(str(item), str(target))
  93. total_files += 1
  94. except Exception as e:
  95. print(f"✗ 移动失败: {item_name}")
  96. print(f" 错误: {e}")
  97. print()
  98. print("=" * 60)
  99. print("迁移完成!")
  100. print("=" * 60)
  101. print(f"移动的目录数: {total_dirs}")
  102. print(f"移动的文件数: {total_files}")
  103. if skipped_items:
  104. print(f"跳过的项目数: {len(skipped_items)}")
  105. print(f"跳过的项目: {', '.join(skipped_items)}")
  106. print()
  107. # 检查 data 目录是否为空
  108. remaining_items = list(old_data_dir.iterdir())
  109. if not remaining_items:
  110. print(f"✓ 源目录 {old_data_dir} 已空,可以删除")
  111. response = input("是否删除空的 data/ 目录?(y/n): ")
  112. if response.lower() == 'y':
  113. old_data_dir.rmdir()
  114. print(f"✓ 已删除 {old_data_dir}")
  115. else:
  116. print(f"⚠️ 源目录 {old_data_dir} 中还有以下内容:")
  117. for item in remaining_items:
  118. print(f" - {item.name}")
  119. print("这些可能是非缓存数据,已保留在原位置")
  120. print()
  121. print("=" * 60)
  122. print("下一步操作:")
  123. print("1. 验证迁移结果:检查 cache/data/ 目录中的数据是否完整")
  124. print("2. 如果一切正常,可以删除旧的 data/ 目录(如果为空)")
  125. print("3. 更新你的脚本或配置,使用新的路径")
  126. print("=" * 60)
  127. if __name__ == "__main__":
  128. migrate_data_to_cache()