Finish
This commit is contained in:
parent
85b49ddf0f
commit
39394caa8e
3 changed files with 249 additions and 15 deletions
|
@ -80,37 +80,50 @@ class DatabaseManager:
|
|||
try:
|
||||
cur = self.connection.cursor()
|
||||
|
||||
# Build the UPDATE query dynamically
|
||||
# Build the INSERT and UPDATE query dynamically
|
||||
insert_placeholders = []
|
||||
insert_values = [key_value] # Start with key_value
|
||||
|
||||
set_clauses = []
|
||||
values = []
|
||||
update_values = []
|
||||
|
||||
for field, value in fields.items():
|
||||
if value == "NOW()":
|
||||
# Special handling for NOW()
|
||||
insert_placeholders.append("NOW()")
|
||||
set_clauses.append(f"{field} = NOW()")
|
||||
else:
|
||||
insert_placeholders.append("%s")
|
||||
insert_values.append(value)
|
||||
set_clauses.append(f"{field} = %s")
|
||||
values.append(value)
|
||||
update_values.append(value)
|
||||
|
||||
# Add schema prefix if table doesn't already have it
|
||||
full_table_name = table if '.' in table else f"gas_station_1.{table}"
|
||||
|
||||
# Build the complete query
|
||||
query = f"""
|
||||
INSERT INTO {full_table_name} ({key_field}, {', '.join(fields.keys())})
|
||||
VALUES (%s, {', '.join(['%s'] * len(fields))})
|
||||
VALUES (%s, {', '.join(insert_placeholders)})
|
||||
ON CONFLICT ({key_field})
|
||||
DO UPDATE SET {', '.join(set_clauses)}
|
||||
"""
|
||||
|
||||
# Add key_value to the beginning of values list
|
||||
all_values = [key_value] + list(fields.values()) + values
|
||||
# Combine values for the query: insert_values + update_values
|
||||
all_values = insert_values + update_values
|
||||
|
||||
logger.debug(f"SQL Query: {query}")
|
||||
logger.debug(f"Values: {all_values}")
|
||||
|
||||
cur.execute(query, all_values)
|
||||
self.connection.commit()
|
||||
cur.close()
|
||||
logger.info(f"Updated {table} for {key_field}={key_value}")
|
||||
logger.info(f"✅ Updated {table} for {key_field}={key_value} with fields: {fields}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to execute update on {table}: {e}")
|
||||
logger.error(f"❌ Failed to execute update on {table}: {e}")
|
||||
logger.debug(f"Query: {query if 'query' in locals() else 'Query not built'}")
|
||||
logger.debug(f"Values: {all_values if 'all_values' in locals() else 'Values not prepared'}")
|
||||
if self.connection:
|
||||
self.connection.rollback()
|
||||
return False
|
||||
|
|
|
@ -453,6 +453,7 @@ def execute_postgresql_update_combined(node, action, detection_result, branch_re
|
|||
key_value = key_value_template.format(**action_context)
|
||||
|
||||
logger.info(f"Executing database update: table={table}, {key_field}={key_value}")
|
||||
logger.debug(f"Available branch results: {list(branch_results.keys())}")
|
||||
|
||||
# Process field mappings
|
||||
mapped_fields = {}
|
||||
|
@ -461,26 +462,38 @@ def execute_postgresql_update_combined(node, action, detection_result, branch_re
|
|||
mapped_value = resolve_field_mapping(value_template, branch_results, action_context)
|
||||
if mapped_value is not None:
|
||||
mapped_fields[db_field] = mapped_value
|
||||
logger.debug(f"Mapped field: {db_field} = {mapped_value}")
|
||||
logger.info(f"Mapped field: {db_field} = {mapped_value}")
|
||||
else:
|
||||
logger.warning(f"Could not resolve field mapping for {db_field}: {value_template}")
|
||||
logger.debug(f"Available branch results: {branch_results}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error mapping field {db_field} with template '{value_template}': {e}")
|
||||
import traceback
|
||||
logger.debug(f"Field mapping error traceback: {traceback.format_exc()}")
|
||||
|
||||
if not mapped_fields:
|
||||
logger.warning("No fields mapped successfully, skipping database update")
|
||||
logger.debug(f"Branch results available: {branch_results}")
|
||||
logger.debug(f"Field templates: {fields}")
|
||||
return
|
||||
|
||||
# Add updated_at field automatically
|
||||
mapped_fields["updated_at"] = "NOW()"
|
||||
|
||||
# Execute the database update
|
||||
logger.info(f"Attempting database update with fields: {mapped_fields}")
|
||||
success = node["db_manager"].execute_update(table, key_field, key_value, mapped_fields)
|
||||
|
||||
if success:
|
||||
logger.info(f"Successfully updated database: {table} with {len(mapped_fields)} fields")
|
||||
logger.info(f"✅ Successfully updated database: {table} with {len(mapped_fields)} fields")
|
||||
logger.info(f"Updated fields: {mapped_fields}")
|
||||
else:
|
||||
logger.error(f"Failed to update database: {table}")
|
||||
logger.error(f"❌ Failed to update database: {table}")
|
||||
logger.error(f"Attempted update with: {key_field}={key_value}, fields={mapped_fields}")
|
||||
|
||||
except KeyError as e:
|
||||
logger.error(f"Missing required field in postgresql_update_combined action: {e}")
|
||||
logger.debug(f"Action config: {action}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error in postgresql_update_combined action: {e}")
|
||||
import traceback
|
||||
|
@ -489,28 +502,68 @@ def execute_postgresql_update_combined(node, action, detection_result, branch_re
|
|||
def resolve_field_mapping(value_template, branch_results, action_context):
|
||||
"""Resolve field mapping templates like {car_brand_cls_v1.brand}."""
|
||||
try:
|
||||
logger.debug(f"Resolving field mapping: '{value_template}'")
|
||||
logger.debug(f"Available branch results: {list(branch_results.keys())}")
|
||||
|
||||
# Handle simple context variables first (non-branch references)
|
||||
if not '.' in value_template:
|
||||
return value_template.format(**action_context)
|
||||
result = value_template.format(**action_context)
|
||||
logger.debug(f"Simple template resolved: '{value_template}' -> '{result}'")
|
||||
return result
|
||||
|
||||
# Handle branch result references like {model_id.field}
|
||||
import re
|
||||
branch_refs = re.findall(r'\{([^}]+\.[^}]+)\}', value_template)
|
||||
logger.debug(f"Found branch references: {branch_refs}")
|
||||
|
||||
resolved_template = value_template
|
||||
for ref in branch_refs:
|
||||
try:
|
||||
model_id, field_name = ref.split('.', 1)
|
||||
logger.debug(f"Processing branch reference: model_id='{model_id}', field_name='{field_name}'")
|
||||
|
||||
if model_id in branch_results:
|
||||
branch_data = branch_results[model_id]
|
||||
logger.debug(f"Branch '{model_id}' data: {branch_data}")
|
||||
|
||||
if field_name in branch_data:
|
||||
field_value = branch_data[field_name]
|
||||
resolved_template = resolved_template.replace(f'{{{ref}}}', str(field_value))
|
||||
logger.debug(f"Resolved {ref} to {field_value}")
|
||||
logger.info(f"✅ Resolved {ref} to '{field_value}'")
|
||||
else:
|
||||
logger.warning(f"Field '{field_name}' not found in branch '{model_id}' results. Available fields: {list(branch_data.keys())}")
|
||||
return None
|
||||
logger.warning(f"Field '{field_name}' not found in branch '{model_id}' results.")
|
||||
logger.debug(f"Available fields in '{model_id}': {list(branch_data.keys())}")
|
||||
|
||||
# Try alternative field names based on the class result and model type
|
||||
if isinstance(branch_data, dict):
|
||||
fallback_value = None
|
||||
|
||||
# First, try the exact field name
|
||||
if field_name in branch_data:
|
||||
fallback_value = branch_data[field_name]
|
||||
# Then try 'class' field as fallback
|
||||
elif 'class' in branch_data:
|
||||
fallback_value = branch_data['class']
|
||||
logger.info(f"Using 'class' field as fallback for '{field_name}': '{fallback_value}'")
|
||||
# For brand models, also check if the class name exists as a key
|
||||
elif field_name == 'brand' and branch_data.get('class') in branch_data:
|
||||
fallback_value = branch_data[branch_data['class']]
|
||||
logger.info(f"Found brand value using class name as key: '{fallback_value}'")
|
||||
# For body_type models, also check if the class name exists as a key
|
||||
elif field_name == 'body_type' and branch_data.get('class') in branch_data:
|
||||
fallback_value = branch_data[branch_data['class']]
|
||||
logger.info(f"Found body_type value using class name as key: '{fallback_value}'")
|
||||
|
||||
if fallback_value is not None:
|
||||
resolved_template = resolved_template.replace(f'{{{ref}}}', str(fallback_value))
|
||||
logger.info(f"✅ Resolved {ref} to '{fallback_value}' (using fallback)")
|
||||
else:
|
||||
logger.error(f"No suitable field found for '{field_name}' in branch '{model_id}'")
|
||||
logger.debug(f"Branch data structure: {branch_data}")
|
||||
return None
|
||||
else:
|
||||
logger.error(f"Branch data for '{model_id}' is not a dictionary: {type(branch_data)}")
|
||||
return None
|
||||
else:
|
||||
logger.warning(f"Branch '{model_id}' not found in results. Available branches: {list(branch_results.keys())}")
|
||||
return None
|
||||
|
@ -521,6 +574,7 @@ def resolve_field_mapping(value_template, branch_results, action_context):
|
|||
# Format any remaining simple variables
|
||||
try:
|
||||
final_value = resolved_template.format(**action_context)
|
||||
logger.debug(f"Final resolved value: '{final_value}'")
|
||||
return final_value
|
||||
except KeyError as e:
|
||||
logger.warning(f"Could not resolve context variable in template: {e}")
|
||||
|
@ -528,6 +582,8 @@ def resolve_field_mapping(value_template, branch_results, action_context):
|
|||
|
||||
except Exception as e:
|
||||
logger.error(f"Error resolving field mapping '{value_template}': {e}")
|
||||
import traceback
|
||||
logger.debug(f"Field mapping error traceback: {traceback.format_exc()}")
|
||||
return None
|
||||
|
||||
def run_detection_with_tracking(frame, node, context=None):
|
||||
|
@ -1720,6 +1776,12 @@ def run_pipeline(frame, node: dict, return_bbox: bool=False, context=None):
|
|||
if result:
|
||||
branch_results[br["modelId"]] = result
|
||||
logger.info(f"Branch {br['modelId']} completed: {result}")
|
||||
|
||||
# Collect nested branch results if they exist
|
||||
if "branch_results" in result:
|
||||
for nested_id, nested_result in result["branch_results"].items():
|
||||
branch_results[nested_id] = nested_result
|
||||
logger.info(f"Collected nested branch result: {nested_id} = {nested_result}")
|
||||
except Exception as e:
|
||||
logger.error(f"Branch {br['modelId']} failed: {e}")
|
||||
else:
|
||||
|
@ -1760,6 +1822,12 @@ def run_pipeline(frame, node: dict, return_bbox: bool=False, context=None):
|
|||
if result:
|
||||
branch_results[br["modelId"]] = result
|
||||
logger.info(f"Branch {br['modelId']} completed: {result}")
|
||||
|
||||
# Collect nested branch results if they exist
|
||||
if "branch_results" in result:
|
||||
for nested_id, nested_result in result["branch_results"].items():
|
||||
branch_results[nested_id] = nested_result
|
||||
logger.info(f"Collected nested branch result: {nested_id} = {nested_result}")
|
||||
else:
|
||||
logger.warning(f"Branch {br['modelId']} returned no result")
|
||||
except Exception as e:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue