Compare commits

..

6 Commits

Author SHA1 Message Date
whm
d80dd0f5ec 1.补充数据加到error表中,推理的改回之前的 2026-03-16 11:00:53 +08:00
lhx
65744e28dd 删除对象冲突 2026-03-16 10:26:19 +08:00
lhx
beea67482d 合并代码 2026-03-16 10:24:24 +08:00
whm
a577b8ef07 1.把日更字段和补全历史数据字段分开 2026-03-16 10:12:21 +08:00
whm
3f7b839e0a Merge branch 'main' of https://gitea.yuxindazhineng.com/admin/railway_cloud
# Conflicts:
#	app/models/lose_data.py
2026-03-15 12:33:32 +08:00
whm
e5de18e80f 1.补偿数据上传 2026-03-15 12:30:53 +08:00
6 changed files with 87 additions and 64 deletions

View File

@@ -613,8 +613,8 @@ def refresh_today_data(request: TodayDataRequest, db: Session = Depends(get_db))
return DataResponse( return DataResponse(
code=ResponseCode.QUERY_FAILED, code=ResponseCode.QUERY_FAILED,
message=f"定时任务触发失败:{str(e)}", message=f"定时任务触发失败:{str(e)}",
total=len(daily_data), total=0,
data={} data=[]
) )
# account_id获取所有断面数据 # account_id获取所有断面数据
@router.post("/get_all_section_by_account", response_model=DataResponse) @router.post("/get_all_section_by_account", response_model=DataResponse)

View File

@@ -0,0 +1,10 @@
from sqlalchemy import Column, Integer, String
from ..core.database import Base
class ErrorLinecode(Base):
"""推理推不出来的水准线路(如全为冬休),记录到该表。数据库表 id 必须为 AUTO_INCREMENT。"""
__tablename__ = "error_linecode"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
linecode = Column(String(255), nullable=False, comment="水准线路编码", index=True)

View File

@@ -27,23 +27,3 @@ class LevelData(Base):
column.name: getattr(self, column.name) column.name: getattr(self, column.name)
for column in self.__table__.columns for column in self.__table__.columns
} }
class LoseData(Base):
__tablename__ = "lose_data"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
account_id = Column(String(100), nullable=False, comment="水准线路编码", index=True)
NYID = Column(String(100), nullable=False, comment="期数id", index=True)
linecode = Column(String(100), nullable=False, comment="水准线路编码", index=True)
benchmarkids = Column(String(100), comment="工作基点名称序列")
point_id = Column(String(100), nullable=False, comment="观测点id", index=True)
section_id = Column(String(100), nullable=False, comment="所属断面id")
lose_data = Column(String(100), comment="水准观测类型")
# 模型转字典
def to_dict(self):
"""将模型实例转换为字典,支持 Pydantic 序列化"""
return {
column.name: getattr(self, column.name)
for column in self.__table__.columns
}

View File

@@ -1,21 +1,21 @@
from sqlalchemy import Column, Integer, String, DateTime from sqlalchemy import Column, Integer, String
from ..core.database import Base from ..core.database import Base
class LoseData(Base): class LoseData(Base):
"""缺失数据记录表:记录各水准线路(期数)的原始/沉降数据缺失情况"""
__tablename__ = "lose_data" __tablename__ = "lose_data"
__table_args__ = {"extend_existing": True}
id = Column(Integer, primary_key=True, index=True, autoincrement=True) id = Column(Integer, primary_key=True, index=True, autoincrement=True, comment="ID")
account_id = Column(String(100), nullable=False, comment="水准线路编码", index=True) account_id = Column(Integer, nullable=False, comment="账户id", index=True)
NYID = Column(String(100), nullable=False, comment="期数id", index=True) NYID = Column(String(100), nullable=False, comment="期数ID", index=True)
linecode = Column(String(100), nullable=False, comment="水准线路编码", index=True) linecode = Column(String(255), nullable=False, default="0", comment="水准线路编码", index=True)
benchmarkids = Column(String(100), comment="工作基点名称序列") lose_data = Column(Integer, nullable=False, default=0, comment="缺失的数据默认是0")
point_id = Column(String(100), nullable=False, comment="观测点id", index=True) section_id = Column(String(255), nullable=True, comment="所属断面id")
section_id = Column(String(100), nullable=False, comment="所属断面id") point_id = Column(String(100), nullable=False, comment="测点ID")
lose_data = Column(String(100), comment="水准观测类型")
# 模型转字典
def to_dict(self): def to_dict(self):
"""将模型实例转换为字典,支持 Pydantic 序列化"""
return { return {
column.name: getattr(self, column.name) column.name: getattr(self, column.name)
for column in self.__table__.columns for column in self.__table__.columns

View File

@@ -65,7 +65,7 @@ class ConstructionMonitorUtils:
return compatible_map return compatible_map
def get_due_data(self, input_data: List[List[Dict]], start: int = 0, end: int = 0, current_date: datetime = None) -> Dict[str, List[Dict]]: def get_due_data(self, input_data: List[List[Dict]], start: int = 0, end: int = 0, current_date: datetime = None) -> Dict[str, List[Dict]]:
result = {"winter": [], "data": [], "error_data": []} result = {"winter": [], "data": [], "error_data": [], "error_linecodes": []}
if not input_data: if not input_data:
return result return result
@@ -139,12 +139,12 @@ class ConstructionMonitorUtils:
continue continue
if not base_condition: if not base_condition:
# 当前为冬休历史全是冬休 → 视为数据未补全remaining 固定为 -365 # 当前为冬休历史全是冬休 → 归入冬休;若本次是冬休且推不出,记入 error_linecodes 供写入 error_linecode 表
result["winter"].append(item_copy)
if latest_condition == "冬休": if latest_condition == "冬休":
item_copy["remaining"] = -365 linecode = latest_item.get("__linecode")
result["data"].append(item_copy) if linecode and linecode not in result["error_linecodes"]:
else: result["error_linecodes"].append(linecode)
result["winter"].append(item_copy)
continue continue
# 核心修改:冬休回溯场景下调整测量间隔(基准周期) # 核心修改:冬休回溯场景下调整测量间隔(基准周期)

View File

@@ -17,6 +17,7 @@ from ..services.account import AccountService
from ..models.daily import DailyData from ..models.daily import DailyData
from ..models.settlement_data import SettlementData from ..models.settlement_data import SettlementData
from ..models.level_data import LevelData from ..models.level_data import LevelData
from ..models.error_linecode import ErrorLinecode
from ..services.settlement_data import SettlementDataService from ..services.settlement_data import SettlementDataService
from typing import List, Tuple, Any from typing import List, Tuple, Any
from ..utils.construction_monitor import ConstructionMonitorUtils from ..utils.construction_monitor import ConstructionMonitorUtils
@@ -243,21 +244,37 @@ def scheduled_get_max_nyid_by_point_id(start: int = 0,end: int = 0):
account_service = AccountService() account_service = AccountService()
monitor = ConstructionMonitorUtils() monitor = ConstructionMonitorUtils()
logger.info("正在查询水准线路列表…")
linecodes = [r[0] for r in db.query(LevelData.linecode).distinct().all()] linecodes = [r[0] for r in db.query(LevelData.linecode).distinct().all()]
linecode_level_settlement: List[Tuple[str, Any, dict]] = [] logger.info(f"{len(linecodes)} 个水准线路,开始拉取多期沉降…")
for linecode in linecodes: # 每个 linecode 传多期沉降(按 NYID 降序),供冬休「一直推」直到推出或推不出
level_instance = level_service.get_last_by_linecode(db, linecode) input_data: List[List[dict]] = []
if not level_instance: for idx, linecode in enumerate(linecodes):
level_list = level_service.get_by_linecode(db, linecode)
if not level_list:
continue continue
nyid = level_instance.NYID # 按 NYID 降序(最新在前),最多取 30 期
settlement_dict = settlement_service.get_one_dict_by_nyid(db, nyid) level_list_sorted = sorted(
if not settlement_dict: level_list,
continue key=lambda x: int(x.NYID) if str(x.NYID).isdigit() else 0,
settlement_dict['__linecode'] = linecode reverse=True,
settlement_dict['__level_data'] = level_instance.to_dict() )[:30]
linecode_level_settlement.append((linecode, level_instance, settlement_dict)) point_data_for_linecode: List[dict] = []
level_latest = level_list_sorted[0]
input_data = [[s] for (_, _, s) in linecode_level_settlement] for level_instance in level_list_sorted:
nyid = level_instance.NYID
settlement_dict = settlement_service.get_one_dict_by_nyid(db, nyid)
if not settlement_dict:
continue
settlement_dict["__linecode"] = linecode
# 仅最新一期带 __level_data供后续写 daily 用
settlement_dict["__level_data"] = level_latest.to_dict()
point_data_for_linecode.append(settlement_dict)
if point_data_for_linecode:
input_data.append(point_data_for_linecode)
if (idx + 1) % 50 == 0 or idx == len(linecodes) - 1:
logger.info(f"已处理线路 {idx + 1}/{len(linecodes)},当前共 {len(input_data)} 条可推理")
logger.info(f"多期沉降拉取完成,共 {len(input_data)} 条线路,开始推理…")
if not input_data: if not input_data:
logger.warning("未找到任何 linecode 对应的最新期沉降数据,跳过写 daily") logger.warning("未找到任何 linecode 对应的最新期沉降数据,跳过写 daily")
db.execute(text(f"TRUNCATE TABLE {DailyData.__tablename__}")) db.execute(text(f"TRUNCATE TABLE {DailyData.__tablename__}"))
@@ -267,7 +284,23 @@ def scheduled_get_max_nyid_by_point_id(start: int = 0,end: int = 0):
# 2. 计算到期数据remaining / 冬休等) # 2. 计算到期数据remaining / 冬休等)
daily_data = monitor.get_due_data(input_data, start=start, end=end) daily_data = monitor.get_due_data(input_data, start=start, end=end)
data = daily_data['data'] logger.info("推理完成")
data = daily_data["data"]
# 冬休一直推、推不出来的 linecode 写入 error_linecode 表(表 id 需为 AUTO_INCREMENT
try:
for linecode in daily_data.get("error_linecodes", []):
if not linecode:
continue
exists = db.query(ErrorLinecode).filter(ErrorLinecode.linecode == linecode).first()
if not exists:
db.add(ErrorLinecode(linecode=linecode))
if daily_data.get("error_linecodes"):
logger.info(f"推理推不出来的线路将写入 error_linecode: {daily_data['error_linecodes']}")
except Exception as elc:
db.rollback()
logger.warning(
f"error_linecode 写入失败(请确保表 id 为 AUTO_INCREMENT: {elc},已跳过,继续写 daily"
)
logger.info(f"按 level_data 最新期获取数据完成,共{len(data)}条有效记录") logger.info(f"按 level_data 最新期获取数据完成,共{len(data)}条有效记录")
# 3. 关联 level / checkpoint / section / accountlevel 已带在 __level_data # 3. 关联 level / checkpoint / section / accountlevel 已带在 __level_data