fix: Refine EAV writing logic in session metrics upsert function
- Updated the `upsert_session_metrics_from_csv_mapped` function to ensure EAV writes are only skipped when the `source_field` is populated, preventing duplicate storage. - Enhanced unit tests to cover scenarios where the `source_field` is set but the corresponding column is empty, ensuring correct EAV behavior. - Adjusted test cases to reflect changes in the handling of `hr_avg` and other metrics, improving overall test coverage and accuracy.
This commit is contained in:
parent
9d5e16455c
commit
c9d71c0179
|
|
@ -260,15 +260,18 @@ def upsert_session_metrics_from_csv_mapped(
|
||||||
nur in ``activity_log``-Kernfeldern).
|
nur in ``activity_log``-Kernfeldern).
|
||||||
|
|
||||||
Kernfelder schreibt der Executor nach ``activity_log``; hier keine EAV-Zeilen für Registry-Keys.
|
Kernfelder schreibt der Executor nach ``activity_log``; hier keine EAV-Zeilen für Registry-Keys.
|
||||||
Bei gesetztem ``training_parameters.source_field`` ist die Spalte kanonisch — kein EAV-Schreiben.
|
|
||||||
|
Hat ein Parameter ``source_field`` (Semantik aus ``activity_log``), wird EAV nur dann **nicht**
|
||||||
|
geschrieben, wenn diese Spalte nach dem Import bereits befüllt ist — sonst gäbe es doppelte
|
||||||
|
Speicherung und der Merge würde ohnehin die Spalte bevorzugen. Ist die Spalte leer (z. B. Feld
|
||||||
|
nur noch über EAV / Custom-Mapping, ohne Registry-Patch), schreibt der Import den Wert aus
|
||||||
|
``mapped`` nach EAV — analog zum Lesepfad (Spalte zuerst, sonst EAV).
|
||||||
"""
|
"""
|
||||||
cur.execute(
|
cur.execute("SELECT * FROM activity_log WHERE id = %s", (activity_log_id,))
|
||||||
"SELECT profile_id FROM activity_log WHERE id = %s",
|
|
||||||
(activity_log_id,),
|
|
||||||
)
|
|
||||||
row = cur.fetchone()
|
row = cur.fetchone()
|
||||||
if not row or str(row["profile_id"]) != str(profile_id):
|
if not row or str(row["profile_id"]) != str(profile_id):
|
||||||
return
|
return
|
||||||
|
header = dict(row)
|
||||||
schema = resolve_activity_attribute_schema(cur, training_category, training_type_id)
|
schema = resolve_activity_attribute_schema(cur, training_category, training_type_id)
|
||||||
for spec in schema:
|
for spec in schema:
|
||||||
pkey = spec["key"]
|
pkey = spec["key"]
|
||||||
|
|
@ -281,6 +284,8 @@ def upsert_session_metrics_from_csv_mapped(
|
||||||
continue
|
continue
|
||||||
sf_raw = spec.get("source_field")
|
sf_raw = spec.get("source_field")
|
||||||
if sf_raw is not None and str(sf_raw).strip():
|
if sf_raw is not None and str(sf_raw).strip():
|
||||||
|
col = str(sf_raw).strip()
|
||||||
|
if col in header and header[col] is not None:
|
||||||
continue
|
continue
|
||||||
tid = spec["training_parameter_id"]
|
tid = spec["training_parameter_id"]
|
||||||
dt = spec["data_type"]
|
dt = spec["data_type"]
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,10 @@ def test_upsert_csv_skips_eav_when_source_field_maps_activity_log(mock_schema):
|
||||||
self.asm_inserts += 1
|
self.asm_inserts += 1
|
||||||
|
|
||||||
def fetchone(self):
|
def fetchone(self):
|
||||||
return {"profile_id": "00000000-0000-0000-0000-000000000001"}
|
return {
|
||||||
|
"profile_id": "00000000-0000-0000-0000-000000000001",
|
||||||
|
"hr_avg": 130,
|
||||||
|
}
|
||||||
|
|
||||||
cur = Cur()
|
cur = Cur()
|
||||||
upsert_session_metrics_from_csv_mapped(
|
upsert_session_metrics_from_csv_mapped(
|
||||||
|
|
@ -343,6 +346,45 @@ def test_upsert_csv_skips_eav_when_source_field_maps_activity_log(mock_schema):
|
||||||
assert cur.asm_inserts == 0
|
assert cur.asm_inserts == 0
|
||||||
|
|
||||||
|
|
||||||
|
@patch("data_layer.activity_session_metrics.resolve_activity_attribute_schema")
|
||||||
|
def test_upsert_csv_writes_eav_when_source_field_but_column_empty(mock_schema):
|
||||||
|
"""source_field gesetzt, activity_log-Spalte leer — Wert aus mapped nur in EAV (kein Registry-Patch)."""
|
||||||
|
mock_schema.return_value = [
|
||||||
|
{
|
||||||
|
"key": "avg_hr",
|
||||||
|
"training_parameter_id": 42,
|
||||||
|
"data_type": "integer",
|
||||||
|
"validation_rules": {"min": 30, "max": 220},
|
||||||
|
"source_field": "hr_avg",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
class Cur:
|
||||||
|
def __init__(self):
|
||||||
|
self.asm_inserts = 0
|
||||||
|
|
||||||
|
def execute(self, sql, params=None):
|
||||||
|
if "INSERT INTO activity_session_metrics" in sql:
|
||||||
|
self.asm_inserts += 1
|
||||||
|
|
||||||
|
def fetchone(self):
|
||||||
|
return {
|
||||||
|
"profile_id": "00000000-0000-0000-0000-000000000001",
|
||||||
|
"hr_avg": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = Cur()
|
||||||
|
upsert_session_metrics_from_csv_mapped(
|
||||||
|
cur,
|
||||||
|
"00000000-0000-0000-0000-000000000001",
|
||||||
|
"00000000-0000-0000-0000-000000000002",
|
||||||
|
{"avg_hr": 130},
|
||||||
|
"cardio",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
assert cur.asm_inserts == 1
|
||||||
|
|
||||||
|
|
||||||
@patch("data_layer.activity_session_metrics.resolve_activity_attribute_schema")
|
@patch("data_layer.activity_session_metrics.resolve_activity_attribute_schema")
|
||||||
def test_upsert_csv_writes_eav_when_no_source_field(mock_schema):
|
def test_upsert_csv_writes_eav_when_no_source_field(mock_schema):
|
||||||
mock_schema.return_value = [
|
mock_schema.return_value = [
|
||||||
|
|
@ -364,7 +406,7 @@ def test_upsert_csv_writes_eav_when_no_source_field(mock_schema):
|
||||||
self.asm_inserts += 1
|
self.asm_inserts += 1
|
||||||
|
|
||||||
def fetchone(self):
|
def fetchone(self):
|
||||||
return {"profile_id": "00000000-0000-0000-0000-000000000001"}
|
return {"profile_id": "00000000-0000-0000-0000-000000000001", "hr_avg": None}
|
||||||
|
|
||||||
cur = Cur()
|
cur = Cur()
|
||||||
upsert_session_metrics_from_csv_mapped(
|
upsert_session_metrics_from_csv_mapped(
|
||||||
|
|
@ -390,7 +432,7 @@ def test_upsert_csv_skips_eav_when_mapped_key_not_in_profile_schema(mock_resolve
|
||||||
self.asm_inserts += 1
|
self.asm_inserts += 1
|
||||||
|
|
||||||
def fetchone(self):
|
def fetchone(self):
|
||||||
return {"profile_id": "00000000-0000-0000-0000-000000000001"}
|
return {"profile_id": "00000000-0000-0000-0000-000000000001", "hr_avg": None}
|
||||||
|
|
||||||
cur = Cur()
|
cur = Cur()
|
||||||
upsert_session_metrics_from_csv_mapped(
|
upsert_session_metrics_from_csv_mapped(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user