Start fixing forecast service 18
This commit is contained in:
@@ -122,15 +122,17 @@ class ForecastingService:
|
|||||||
|
|
||||||
# Metadata
|
# Metadata
|
||||||
created_at=forecast.created_at,
|
created_at=forecast.created_at,
|
||||||
processing_time_ms=forecast.processing_time_ms,
|
processing_time_ms=int((datetime.now() - start_time).total_seconds() * 1000),
|
||||||
features_used=forecast.features_used
|
features_used=forecast.features_used
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
processing_time = int((datetime.now() - start_time).total_seconds() * 1000)
|
||||||
logger.error("Error generating forecast",
|
logger.error("Error generating forecast",
|
||||||
error=str(e),
|
error=str(e),
|
||||||
product=request.product_name,
|
product=request.product_name,
|
||||||
tenant_id=tenant_id)
|
tenant_id=tenant_id,
|
||||||
|
processing_time=processing_time)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
async def _get_latest_model_with_fallback(
|
async def _get_latest_model_with_fallback(
|
||||||
@@ -422,6 +424,8 @@ class ForecastingService:
|
|||||||
) -> Forecast:
|
) -> Forecast:
|
||||||
"""Save forecast to database"""
|
"""Save forecast to database"""
|
||||||
|
|
||||||
|
start_time = datetime.now()
|
||||||
|
|
||||||
forecast = Forecast(
|
forecast = Forecast(
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
product_name=request.product_name,
|
product_name=request.product_name,
|
||||||
|
|||||||
@@ -324,15 +324,18 @@ class BakeryDataProcessor:
|
|||||||
if 'date' not in weather_clean.columns and 'ds' in weather_clean.columns:
|
if 'date' not in weather_clean.columns and 'ds' in weather_clean.columns:
|
||||||
weather_clean = weather_clean.rename(columns={'ds': 'date'})
|
weather_clean = weather_clean.rename(columns={'ds': 'date'})
|
||||||
|
|
||||||
# ✅ FIX: Ensure timezone consistency
|
# 🔧 CRITICAL FIX: Ensure both DataFrames have compatible datetime formats
|
||||||
weather_clean['date'] = pd.to_datetime(weather_clean['date'])
|
weather_clean['date'] = pd.to_datetime(weather_clean['date'])
|
||||||
daily_sales['date'] = pd.to_datetime(daily_sales['date'])
|
daily_sales['date'] = pd.to_datetime(daily_sales['date'])
|
||||||
|
|
||||||
# Remove timezone info from both to make them compatible
|
# ✅ NEW FIX: Normalize both to timezone-naive datetime for merge compatibility
|
||||||
if weather_clean['date'].dt.tz is not None:
|
if weather_clean['date'].dt.tz is not None:
|
||||||
weather_clean['date'] = weather_clean['date'].dt.tz_localize(None)
|
# Convert timezone-aware to UTC then remove timezone info
|
||||||
|
weather_clean['date'] = weather_clean['date'].dt.tz_convert('UTC').dt.tz_localize(None)
|
||||||
|
|
||||||
if daily_sales['date'].dt.tz is not None:
|
if daily_sales['date'].dt.tz is not None:
|
||||||
daily_sales['date'] = daily_sales['date'].dt.tz_localize(None)
|
# Convert timezone-aware to UTC then remove timezone info
|
||||||
|
daily_sales['date'] = daily_sales['date'].dt.tz_convert('UTC').dt.tz_localize(None)
|
||||||
|
|
||||||
# Map weather columns to standard names
|
# Map weather columns to standard names
|
||||||
weather_mapping = {
|
weather_mapping = {
|
||||||
@@ -390,15 +393,19 @@ class BakeryDataProcessor:
|
|||||||
if 'date' not in traffic_clean.columns and 'ds' in traffic_clean.columns:
|
if 'date' not in traffic_clean.columns and 'ds' in traffic_clean.columns:
|
||||||
traffic_clean = traffic_clean.rename(columns={'ds': 'date'})
|
traffic_clean = traffic_clean.rename(columns={'ds': 'date'})
|
||||||
|
|
||||||
# 🔧 FIX: Ensure timezone awareness before merge
|
# 🔧 CRITICAL FIX: Ensure both DataFrames have compatible datetime formats
|
||||||
traffic_clean['date'] = pd.to_datetime(traffic_clean['date'])
|
traffic_clean['date'] = pd.to_datetime(traffic_clean['date'])
|
||||||
|
daily_sales['date'] = pd.to_datetime(daily_sales['date'])
|
||||||
|
|
||||||
# If timezone-naive, localize to UTC
|
# ✅ NEW FIX: Normalize both to timezone-naive datetime for merge compatibility
|
||||||
if traffic_clean['date'].dt.tz is None:
|
# This prevents the "datetime64[ns] and datetime64[ns, UTC]" merge error
|
||||||
traffic_clean['date'] = traffic_clean['date'].dt.tz_localize('UTC')
|
if traffic_clean['date'].dt.tz is not None:
|
||||||
# If already timezone-aware but not UTC, convert to UTC
|
# Convert timezone-aware to UTC then remove timezone info
|
||||||
elif str(traffic_clean['date'].dt.tz) != 'UTC':
|
traffic_clean['date'] = traffic_clean['date'].dt.tz_convert('UTC').dt.tz_localize(None)
|
||||||
traffic_clean['date'] = traffic_clean['date'].dt.tz_convert('UTC')
|
|
||||||
|
if daily_sales['date'].dt.tz is not None:
|
||||||
|
# Convert timezone-aware to UTC then remove timezone info
|
||||||
|
daily_sales['date'] = daily_sales['date'].dt.tz_convert('UTC').dt.tz_localize(None)
|
||||||
|
|
||||||
# Map traffic columns to standard names
|
# Map traffic columns to standard names
|
||||||
traffic_mapping = {
|
traffic_mapping = {
|
||||||
|
|||||||
Reference in New Issue
Block a user