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