This commit is contained in:
lhx
2025-11-18 17:49:38 +08:00
3 changed files with 76 additions and 104 deletions

View File

@@ -90,15 +90,17 @@ class DailyDataService(BaseService[DailyData]):
def get_nyid_by_point_id(
self,
db: Session,
point_ids: List[int] = None,
point_ids: Optional[List[int]] = None,
max_num: int = 1
) -> List[List[dict]]:
"""
获取指定point_id的记录修复子查询中模型对象访问错误同时过滤useflag=0的数据
获取指定point_id的记录每个point_id的前max_num条记录放在同一个子列表中
返回格式:[[point1_records...], [point2_records...]]
"""
# 处理参数默认值
point_ids = point_ids or []
max_num = max(max_num, 1)
if max_num <= 0:
return []
# 窗口函数按point_id分组每组内按NYID降序编号
row_num = over(
@@ -107,60 +109,54 @@ class DailyDataService(BaseService[DailyData]):
order_by=desc(SettlementData.NYID)
).label("row_num")
# 子查询:查询模型的所有字段 + 行号(不保留模型对象,只展平字段)
# 先获取模型的所有字段列表
# 模型字段列表
model_columns = [getattr(SettlementData, col.name) for col in SettlementData.__table__.columns]
# -------------------------- 新增过滤条件useflag IS NOT NULL AND useflag != 0 --------------------------
# 基础条件过滤useflag为0或不存在的记录
# 基础条件
base_conditions = [
SettlementData.useflag.isnot(None), # 确保useflag字段存在非NULL
SettlementData.useflag != 0 # 确保useflag值不为0
SettlementData.useflag.isnot(None),
SettlementData.useflag != 0
]
# 若指定了point_ids添加point_id过滤条件
if point_ids:
base_conditions.append(SettlementData.point_id.in_(point_ids))
# 子查询
subquery = (
select(*model_columns, row_num) # 展开所有字段 + 行号
.where(*base_conditions) # 应用组合条件包含useflag过滤
select(*model_columns, row_num)
.where(*base_conditions)
.subquery()
)
# ------------------------------------------------------------------------------------------------------
# 主查询:筛选行号<=max_num的记录
# 主查询:筛选每个point_id的前max_num
query = (
select(subquery)
.where(subquery.c.row_num <= max_num)
.order_by(subquery.c.point_id, subquery.c.row_num)
)
# 执行查询(结果为包含字段值的行对象)
# 执行查询
results = db.execute(query).all()
grouped: Dict[int, List[dict]] = {}
# 获取模型字段名列表(用于映射行对象到字典)
grouped: Dict[int, List[dict]] = {} # 键point_id该point_id的所有记录子列表
field_names = [col.name for col in SettlementData.__table__.columns]
for row in results:
# 将行对象转换为字典忽略最后一个字段row_num
item_dict = {
field: getattr(row, field)
for field in field_names
}
pid = item_dict["point_id"]
item_dict = {field: getattr(row, field) for field in field_names}
try:
pid = int(item_dict["point_id"]) # 确保point_id为整数
except (KeyError, ValueError):
continue # 跳过无效记录
# 同一point_id的记录放入同一个列表
if pid not in grouped:
grouped[pid] = []
grouped[pid].append(item_dict)
grouped[pid] = [] # 初始化子列表
grouped[pid].append(item_dict) # 追加到子列表
# 按输入point_ids顺序整理结果
# 按输入point_ids顺序整理结果关键每个point_id对应一个子列表
if not point_ids:
point_ids = sorted(grouped.keys())
point_ids = sorted(grouped.keys()) # 若无指定按point_id排序
# 构建[[{}], [{}]]格式
return [
[record] for pid in point_ids for record in grouped.get(pid, [])
]
# 构建最终结果每个point_id的记录作为一个子列表
return [grouped.get(pid, []) for pid in point_ids]
# 获取所有的今日数据
def get_all_daily_data(