fix: Handle invalid MySQL dates (0000-00-00) gracefully
MySQL can contain invalid/zero dates like '0000-00-00' which cannot be parsed with strptime. These should be treated as NULL and converted to the default timestamp (1970-01-01 00:00:00). Changes to _convert_date(): - Check for '0000-00-00' and invalid date strings - Wrap strptime in try/except to catch ValueError - Return None for invalid dates instead of crashing - Updated callers to check for None and use default timestamp This allows the migration to continue even when encountering invalid historical dates in the MySQL database. Fixes: "time data '0000-00-00' does not match format '%Y-%m-%d'" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,7 +19,7 @@ class DataTransformer:
|
|||||||
"""Convert event_date to date object.
|
"""Convert event_date to date object.
|
||||||
|
|
||||||
Handles multiple input types:
|
Handles multiple input types:
|
||||||
- str: Parse from "YYYY-MM-DD" format
|
- str: Parse from "YYYY-MM-DD" format (returns None for invalid dates like '0000-00-00')
|
||||||
- date: Return as-is
|
- date: Return as-is
|
||||||
- datetime: Extract date component
|
- datetime: Extract date component
|
||||||
|
|
||||||
@@ -27,16 +27,23 @@ class DataTransformer:
|
|||||||
event_date: Date value from MySQL (str or date)
|
event_date: Date value from MySQL (str or date)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
date object
|
date object or None for invalid dates
|
||||||
"""
|
"""
|
||||||
if isinstance(event_date, str):
|
if isinstance(event_date, str):
|
||||||
return datetime.strptime(event_date, "%Y-%m-%d").date()
|
# Handle MySQL invalid dates (0000-00-00, etc)
|
||||||
|
if event_date == '0000-00-00' or not event_date or event_date.startswith('0000'):
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return datetime.strptime(event_date, "%Y-%m-%d").date()
|
||||||
|
except ValueError:
|
||||||
|
# If parsing fails, return None instead of crashing
|
||||||
|
return None
|
||||||
elif isinstance(event_date, datetime):
|
elif isinstance(event_date, datetime):
|
||||||
return event_date.date()
|
return event_date.date()
|
||||||
elif isinstance(event_date, date):
|
elif isinstance(event_date, date):
|
||||||
return event_date
|
return event_date
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported event_date type: {type(event_date)}")
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _convert_time(event_time: Any) -> time:
|
def _convert_time(event_time: Any) -> time:
|
||||||
@@ -121,7 +128,11 @@ class DataTransformer:
|
|||||||
if event_date is not None and event_time is not None:
|
if event_date is not None and event_time is not None:
|
||||||
event_date_obj = DataTransformer._convert_date(event_date)
|
event_date_obj = DataTransformer._convert_date(event_date)
|
||||||
event_time_obj = DataTransformer._convert_time(event_time)
|
event_time_obj = DataTransformer._convert_time(event_time)
|
||||||
event_timestamp = datetime.combine(event_date_obj, event_time_obj)
|
# If date conversion failed (invalid MySQL date), use default timestamp
|
||||||
|
if event_date_obj is None or event_time_obj is None:
|
||||||
|
event_timestamp = datetime(1970, 1, 1, 0, 0, 0)
|
||||||
|
else:
|
||||||
|
event_timestamp = datetime.combine(event_date_obj, event_time_obj)
|
||||||
elif event_date is None or event_time is None:
|
elif event_date is None or event_time is None:
|
||||||
# Log a warning for records with missing date/time
|
# Log a warning for records with missing date/time
|
||||||
missing = []
|
missing = []
|
||||||
@@ -192,7 +203,11 @@ class DataTransformer:
|
|||||||
if event_date is not None and event_time is not None:
|
if event_date is not None and event_time is not None:
|
||||||
event_date_obj = DataTransformer._convert_date(event_date)
|
event_date_obj = DataTransformer._convert_date(event_date)
|
||||||
event_time_obj = DataTransformer._convert_time(event_time)
|
event_time_obj = DataTransformer._convert_time(event_time)
|
||||||
event_timestamp = datetime.combine(event_date_obj, event_time_obj)
|
# If date conversion failed (invalid MySQL date), use default timestamp
|
||||||
|
if event_date_obj is None or event_time_obj is None:
|
||||||
|
event_timestamp = datetime(1970, 1, 1, 0, 0, 0)
|
||||||
|
else:
|
||||||
|
event_timestamp = datetime.combine(event_date_obj, event_time_obj)
|
||||||
elif event_date is None or event_time is None:
|
elif event_date is None or event_time is None:
|
||||||
# Log a warning for records with missing date/time
|
# Log a warning for records with missing date/time
|
||||||
missing = []
|
missing = []
|
||||||
|
|||||||
Reference in New Issue
Block a user