Fix issues
This commit is contained in:
@@ -137,42 +137,7 @@ class EnhancedTrainingService:
|
||||
await self._init_repositories(session)
|
||||
|
||||
try:
|
||||
# Pre-flight check: Verify sales data exists before starting training
|
||||
from app.services.data_client import DataClient
|
||||
data_client = DataClient()
|
||||
sales_data = await data_client.fetch_sales_data(tenant_id, fetch_all=True)
|
||||
|
||||
if not sales_data or len(sales_data) == 0:
|
||||
error_msg = f"No sales data available for tenant {tenant_id}. Please import sales data before starting training."
|
||||
logger.error("Training aborted - no sales data", tenant_id=tenant_id, job_id=job_id)
|
||||
raise ValueError(error_msg)
|
||||
|
||||
# Debug: Analyze the sales data structure to understand product distribution
|
||||
sales_df_debug = pd.DataFrame(sales_data)
|
||||
if 'inventory_product_id' in sales_df_debug.columns:
|
||||
unique_products_found = sales_df_debug['inventory_product_id'].unique()
|
||||
product_counts = sales_df_debug['inventory_product_id'].value_counts().to_dict()
|
||||
|
||||
logger.info("Pre-flight sales data analysis",
|
||||
tenant_id=tenant_id,
|
||||
job_id=job_id,
|
||||
total_sales_records=len(sales_data),
|
||||
unique_products_count=len(unique_products_found),
|
||||
unique_products=unique_products_found.tolist(),
|
||||
records_per_product=product_counts)
|
||||
|
||||
if len(unique_products_found) == 1:
|
||||
logger.warning("POTENTIAL ISSUE: Only ONE unique product found in all sales data",
|
||||
tenant_id=tenant_id,
|
||||
single_product=unique_products_found[0],
|
||||
record_count=len(sales_data))
|
||||
else:
|
||||
logger.warning("No 'inventory_product_id' column found in sales data",
|
||||
tenant_id=tenant_id,
|
||||
columns=list(sales_df_debug.columns))
|
||||
|
||||
logger.info(f"Pre-flight check passed: {len(sales_data)} sales records found",
|
||||
tenant_id=tenant_id, job_id=job_id)
|
||||
# Pre-flight check moved to orchestrator to eliminate duplicate sales data fetching
|
||||
|
||||
# Check if training log already exists, create if not
|
||||
existing_log = await self.training_log_repo.get_log_by_job_id(job_id)
|
||||
@@ -202,12 +167,13 @@ class EnhancedTrainingService:
|
||||
step_details="Data"
|
||||
)
|
||||
|
||||
# Step 1: Prepare training dataset
|
||||
logger.info("Step 1: Preparing and aligning training data")
|
||||
# Step 1: Prepare training dataset (includes sales data validation)
|
||||
logger.info("Step 1: Preparing and aligning training data (with validation)")
|
||||
await self.training_log_repo.update_log_progress(
|
||||
job_id, 10, "data_validation", "running"
|
||||
)
|
||||
|
||||
# Orchestrator now handles sales data validation to eliminate duplicate fetching
|
||||
training_dataset = await self.orchestrator.prepare_training_data(
|
||||
tenant_id=tenant_id,
|
||||
bakery_location=bakery_location,
|
||||
@@ -216,6 +182,10 @@ class EnhancedTrainingService:
|
||||
job_id=job_id
|
||||
)
|
||||
|
||||
# Log the results from orchestrator's unified sales data fetch
|
||||
logger.info(f"Sales data validation completed: {len(training_dataset.sales_data)} records",
|
||||
tenant_id=tenant_id, job_id=job_id)
|
||||
|
||||
await self.training_log_repo.update_log_progress(
|
||||
job_id, 30, "data_preparation_complete", "running"
|
||||
)
|
||||
@@ -285,6 +255,27 @@ class EnhancedTrainingService:
|
||||
# Make sure all data is JSON-serializable before saving to database
|
||||
json_safe_result = make_json_serializable(final_result)
|
||||
|
||||
# Ensure results is a proper dict for database storage
|
||||
if not isinstance(json_safe_result, dict):
|
||||
logger.warning("JSON safe result is not a dict, wrapping it", result_type=type(json_safe_result))
|
||||
json_safe_result = {"training_data": json_safe_result}
|
||||
|
||||
# Double-check JSON serialization by attempting to serialize
|
||||
import json
|
||||
try:
|
||||
json.dumps(json_safe_result)
|
||||
logger.debug("Results successfully JSON-serializable", job_id=job_id)
|
||||
except (TypeError, ValueError) as e:
|
||||
logger.error("Results still not JSON-serializable after cleaning",
|
||||
job_id=job_id, error=str(e))
|
||||
# Create a minimal safe result
|
||||
json_safe_result = {
|
||||
"status": "completed",
|
||||
"job_id": job_id,
|
||||
"models_created": final_result.get("products_trained", 0),
|
||||
"error": "Result serialization failed"
|
||||
}
|
||||
|
||||
await self.training_log_repo.complete_training_log(
|
||||
job_id, results=json_safe_result
|
||||
)
|
||||
@@ -313,6 +304,9 @@ class EnhancedTrainingService:
|
||||
"completed_at": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
# Ensure error result is JSON serializable
|
||||
error_result = make_json_serializable(error_result)
|
||||
|
||||
return self._create_detailed_training_response(error_result)
|
||||
|
||||
async def _store_trained_models(
|
||||
|
||||
Reference in New Issue
Block a user