load_data.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import json
  2. from pathlib import Path
  3. from typing import List
  4. from models.game_data import GameData
  5. from core.db.database import Database
  6. class DataLoader:
  7. """数据加载器,负责加载游戏数据并提供按属性访问的能力"""
  8. def __init__(self):
  9. """初始化数据加载器,只在首次创建时加载数据"""
  10. self._data_cache: List[GameData] = []
  11. self._db = Database()
  12. self._load_data()
  13. @property
  14. def all_data(self) -> List[GameData]:
  15. """获取所有游戏数据"""
  16. return self._data_cache
  17. @property
  18. def flag1_data(self) -> List[GameData]:
  19. """获取所有包含flag=1的解决方案的游戏数据"""
  20. return [
  21. game for game in self._data_cache
  22. if any(solution.flag == 1 for solution in game.solutions)
  23. ]
  24. @property
  25. def flag2_data(self) -> List[GameData]:
  26. """获取所有包含flag=2的解决方案的游戏数据"""
  27. return [
  28. game for game in self._data_cache
  29. if any(solution.flag == 2 for solution in game.solutions)
  30. ]
  31. def get_data_by_flag(self, flag: int) -> List[GameData]:
  32. """根据指定的flag获取游戏数据
  33. Args:
  34. flag: 解决方案的标志值
  35. Returns:
  36. 包含指定flag解决方案的游戏数据列表
  37. """
  38. return [
  39. game for game in self._data_cache
  40. if any(solution.flag == flag for solution in game.solutions)
  41. ]
  42. def _load_data(self):
  43. """加载游戏数据,仅在初始化时调用一次"""
  44. try:
  45. # 首先尝试从数据库加载数据
  46. if self._db.has_game_data():
  47. # 从数据库加载数据
  48. db_data = self._db.get_all_game_data()
  49. self._data_cache = [self._convert_db_to_dto(item) for item in db_data]
  50. print(f"从数据库成功加载 {len(self._data_cache)} 条游戏数据")
  51. return
  52. # 如果数据库中没有数据,则从JSON文件导入
  53. data_path = Path(__file__).parent.parent.parent / 'data' / '24game_data.json'
  54. if not data_path.exists():
  55. raise FileNotFoundError(f"数据文件未找到: {data_path}")
  56. # 导入数据到数据库
  57. self._db.import_json_data(data_path)
  58. # 从数据库加载数据
  59. db_data = self._db.get_all_game_data()
  60. self._data_cache = [self._convert_db_to_dto(item) for item in db_data]
  61. print(f"从JSON导入并加载 {len(self._data_cache)} 条游戏数据")
  62. except json.JSONDecodeError as e:
  63. raise ValueError(f"JSON解析错误: {e}") from e
  64. except Exception as e:
  65. raise RuntimeError(f"数据加载失败: {e}") from e
  66. def _convert_db_to_dto(self, db_item: dict) -> GameData:
  67. """将数据库记录转换为DTO对象
  68. Args:
  69. db_item: 数据库记录
  70. Returns:
  71. 转换后的DTO对象
  72. """
  73. # 创建DTO对象
  74. dto_dict = {
  75. 'id': db_item['id'],
  76. 'n1': db_item['num1'],
  77. 'n2': db_item['num2'],
  78. 'n3': db_item['num3'],
  79. 'n4': db_item['num4'],
  80. 's': []
  81. }
  82. # 添加解法
  83. for solution in db_item['solutions']:
  84. dto_dict['s'].append({
  85. 'c': solution['expression'],
  86. 'f': solution['flag']
  87. })
  88. return GameData.from_dict(dto_dict)