Skip to content

Commit

Permalink
Attempt to fix nested model retrival
Browse files Browse the repository at this point in the history
  • Loading branch information
matteius committed Oct 3, 2024
1 parent ba2ef4a commit 0bd37f5
Showing 1 changed file with 24 additions and 56 deletions.
80 changes: 24 additions & 56 deletions opensensor/collection_apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def create_nested_pipeline(model: Type[BaseModel], prefix="", pipeline=None):
"timestamp": "$timestamp",
}

for field_name, field_type in model.__fields__.items():
for field_name, _ in model.__fields__.items():
if field_name == "timestamp":
continue
lookup_field = (
Expand All @@ -220,32 +220,17 @@ def create_nested_pipeline(model: Type[BaseModel], prefix="", pipeline=None):
unit_field_name = f"{prefix}{mongo_field}_unit"
pipeline["unit"] = f"${unit_field_name}"
match_conditions[unit_field_name] = {"$exists": True}
elif field_name in nested_fields:
nested_model = nested_fields[field_name]
nested_prefix = f"{full_mongo_field_name}."
nested_pipeline, nested_match = create_nested_pipeline(nested_model, nested_prefix)
pipeline[field_name] = nested_pipeline
for k, v in nested_match.items():
match_conditions[f"{nested_prefix}{k}"] = v
else:
pipeline[field_name] = f"${full_mongo_field_name}"
match_conditions[full_mongo_field_name] = {"$exists": True}

if field_name in nested_fields:
if get_origin(field_type.type_) is List:
nested_pipeline, nested_match = create_nested_pipeline(
nested_fields[field_name], "" # Empty prefix for list items
)
pipeline[field_name] = {
"$map": {
"input": f"${full_mongo_field_name}",
"as": "item",
"in": {
k: f"$$item.{v.replace('$', '')}" for k, v in nested_pipeline.items()
},
}
}
match_conditions[full_mongo_field_name] = {"$exists": True, "$ne": []}
else:
nested_pipeline, nested_match = create_nested_pipeline(
nested_fields[field_name], f"{full_mongo_field_name}.", pipeline
)
pipeline[field_name] = nested_pipeline
match_conditions.update({f"{field_name}.{k}": v for k, v in nested_match.items()})

logger.debug(f"Field: {field_name}, Full mongo field name: {full_mongo_field_name}")
logger.debug(f"Resulting pipeline part: {pipeline[field_name]}")

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

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

for field_name, _ in model.__fields__.items():
for field_name, field in model.__fields__.items():
if field_name == "timestamp":
continue
if field_name in nested_fields:
instance_data[field_name] = data.get(field_name)
continue

lookup_field = (
Expand All @@ -270,41 +255,24 @@ def create_model_instance(model: Type[BaseModel], data: dict, target_unit: Optio
# Special handling for the unit field
if field_name == "unit":
unit_field = f"{mongo_field}_unit"
if unit_field in data:
data[field_name] = data[unit_field]
continue

# Handle temperature unit conversion if applicable
if mongo_field in data:
data[field_name] = data[mongo_field]
elif field_name in data:
# If the field_name exists in data, use it
data[field_name] = data[field_name]
elif field_name.lower() in data:
# If the field_name (lowercase) exists in data, use it
data[field_name] = data[field_name.lower()]
else:
# If neither the mongo_field nor the field_name exists, log an error
logger.error(
f"Field '{mongo_field}' or '{field_name}' not found in data for model {model.__name__}"
)
logger.error(f"Available fields in data: {list(data.keys())}")
# You might want to set a default value or raise an exception here

for field_name, nested_model in nested_fields.items():
if field_name in data:
if isinstance(data[field_name], list):
data[field_name] = [
instance_data[field_name] = data.get(unit_field)
elif field_name in nested_fields:
nested_model = nested_fields[field_name]
if isinstance(field.type_, List):
instance_data[field_name] = [
create_model_instance(nested_model, item, target_unit)
for item in data[field_name]
for item in data.get(field_name, [])
]
else:
data[field_name] = create_model_instance(
nested_model, data[field_name], target_unit
nested_data = data.get(field_name, {})
instance_data[field_name] = create_model_instance(
nested_model, nested_data, target_unit
)
else:
instance_data[field_name] = data.get(mongo_field) or data.get(field_name)

logger.debug(f"Creating instance of {model.__name__} with data: {data}")
result = model(**data)
logger.debug(f"Creating instance of {model.__name__} with data: {instance_data}")
result = model(**instance_data)
if isinstance(result, Temperature) and target_unit:
convert_temperature(result, target_unit)
return result
Expand Down

0 comments on commit 0bd37f5

Please sign in to comment.