Skip to content

Commit 0bd37f5

Browse files
committed
Attempt to fix nested model retrival
1 parent ba2ef4a commit 0bd37f5

File tree

1 file changed

+24
-56
lines changed

1 file changed

+24
-56
lines changed

opensensor/collection_apis.py

+24-56
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ def create_nested_pipeline(model: Type[BaseModel], prefix="", pipeline=None):
207207
"timestamp": "$timestamp",
208208
}
209209

210-
for field_name, field_type in model.__fields__.items():
210+
for field_name, _ in model.__fields__.items():
211211
if field_name == "timestamp":
212212
continue
213213
lookup_field = (
@@ -220,32 +220,17 @@ def create_nested_pipeline(model: Type[BaseModel], prefix="", pipeline=None):
220220
unit_field_name = f"{prefix}{mongo_field}_unit"
221221
pipeline["unit"] = f"${unit_field_name}"
222222
match_conditions[unit_field_name] = {"$exists": True}
223+
elif field_name in nested_fields:
224+
nested_model = nested_fields[field_name]
225+
nested_prefix = f"{full_mongo_field_name}."
226+
nested_pipeline, nested_match = create_nested_pipeline(nested_model, nested_prefix)
227+
pipeline[field_name] = nested_pipeline
228+
for k, v in nested_match.items():
229+
match_conditions[f"{nested_prefix}{k}"] = v
223230
else:
224231
pipeline[field_name] = f"${full_mongo_field_name}"
225232
match_conditions[full_mongo_field_name] = {"$exists": True}
226233

227-
if field_name in nested_fields:
228-
if get_origin(field_type.type_) is List:
229-
nested_pipeline, nested_match = create_nested_pipeline(
230-
nested_fields[field_name], "" # Empty prefix for list items
231-
)
232-
pipeline[field_name] = {
233-
"$map": {
234-
"input": f"${full_mongo_field_name}",
235-
"as": "item",
236-
"in": {
237-
k: f"$$item.{v.replace('$', '')}" for k, v in nested_pipeline.items()
238-
},
239-
}
240-
}
241-
match_conditions[full_mongo_field_name] = {"$exists": True, "$ne": []}
242-
else:
243-
nested_pipeline, nested_match = create_nested_pipeline(
244-
nested_fields[field_name], f"{full_mongo_field_name}.", pipeline
245-
)
246-
pipeline[field_name] = nested_pipeline
247-
match_conditions.update({f"{field_name}.{k}": v for k, v in nested_match.items()})
248-
249234
logger.debug(f"Field: {field_name}, Full mongo field name: {full_mongo_field_name}")
250235
logger.debug(f"Resulting pipeline part: {pipeline[field_name]}")
251236

@@ -255,11 +240,11 @@ def create_nested_pipeline(model: Type[BaseModel], prefix="", pipeline=None):
255240

256241
def create_model_instance(model: Type[BaseModel], data: dict, target_unit: Optional[str] = None):
257242
nested_fields = get_nested_fields(model)
243+
instance_data = {}
258244

259-
for field_name, _ in model.__fields__.items():
245+
for field_name, field in model.__fields__.items():
260246
if field_name == "timestamp":
261-
continue
262-
if field_name in nested_fields:
247+
instance_data[field_name] = data.get(field_name)
263248
continue
264249

265250
lookup_field = (
@@ -270,41 +255,24 @@ def create_model_instance(model: Type[BaseModel], data: dict, target_unit: Optio
270255
# Special handling for the unit field
271256
if field_name == "unit":
272257
unit_field = f"{mongo_field}_unit"
273-
if unit_field in data:
274-
data[field_name] = data[unit_field]
275-
continue
276-
277-
# Handle temperature unit conversion if applicable
278-
if mongo_field in data:
279-
data[field_name] = data[mongo_field]
280-
elif field_name in data:
281-
# If the field_name exists in data, use it
282-
data[field_name] = data[field_name]
283-
elif field_name.lower() in data:
284-
# If the field_name (lowercase) exists in data, use it
285-
data[field_name] = data[field_name.lower()]
286-
else:
287-
# If neither the mongo_field nor the field_name exists, log an error
288-
logger.error(
289-
f"Field '{mongo_field}' or '{field_name}' not found in data for model {model.__name__}"
290-
)
291-
logger.error(f"Available fields in data: {list(data.keys())}")
292-
# You might want to set a default value or raise an exception here
293-
294-
for field_name, nested_model in nested_fields.items():
295-
if field_name in data:
296-
if isinstance(data[field_name], list):
297-
data[field_name] = [
258+
instance_data[field_name] = data.get(unit_field)
259+
elif field_name in nested_fields:
260+
nested_model = nested_fields[field_name]
261+
if isinstance(field.type_, List):
262+
instance_data[field_name] = [
298263
create_model_instance(nested_model, item, target_unit)
299-
for item in data[field_name]
264+
for item in data.get(field_name, [])
300265
]
301266
else:
302-
data[field_name] = create_model_instance(
303-
nested_model, data[field_name], target_unit
267+
nested_data = data.get(field_name, {})
268+
instance_data[field_name] = create_model_instance(
269+
nested_model, nested_data, target_unit
304270
)
271+
else:
272+
instance_data[field_name] = data.get(mongo_field) or data.get(field_name)
305273

306-
logger.debug(f"Creating instance of {model.__name__} with data: {data}")
307-
result = model(**data)
274+
logger.debug(f"Creating instance of {model.__name__} with data: {instance_data}")
275+
result = model(**instance_data)
308276
if isinstance(result, Temperature) and target_unit:
309277
convert_temperature(result, target_unit)
310278
return result

0 commit comments

Comments
 (0)