Files
feiqiu-ETL/etl_billiards/utils/ods_record_utils.py

56 lines
1.6 KiB
Python

# -*- coding: utf-8 -*-
"""Shared helpers for ODS/API record normalization."""
from __future__ import annotations
from typing import Iterable
def merge_record_layers(record: dict) -> dict:
"""Flatten nested data/settleList layers into a single dict."""
merged = record
data_part = merged.get("data")
while isinstance(data_part, dict):
merged = {**data_part, **merged}
data_part = data_part.get("data")
settle_inner = merged.get("settleList")
if isinstance(settle_inner, dict):
merged = {**settle_inner, **merged}
return merged
def get_value_case_insensitive(record: dict | None, col: str | None):
"""Fetch column value without case sensitivity."""
if record is None or col is None:
return None
if col in record:
return record.get(col)
col_lower = col.lower()
for k, v in record.items():
if isinstance(k, str) and k.lower() == col_lower:
return v
return None
def normalize_pk_value(value):
"""Normalize PK value (e.g., digit string -> int)."""
if value is None:
return None
if isinstance(value, str) and value.isdigit():
try:
return int(value)
except Exception:
return value
return value
def pk_tuple_from_record(record: dict, pk_cols: Iterable[str]) -> tuple | None:
"""Extract PK tuple from a record."""
merged = merge_record_layers(record)
values = []
for col in pk_cols:
val = normalize_pk_value(get_value_case_insensitive(merged, col))
if val is None or val == "":
return None
values.append(val)
return tuple(values)