From a7d2d501fbc9a69978f4919bbf6225b8d5781ff7 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 4 Jan 2026 16:04:15 +0100 Subject: [PATCH] fix: Use timezone-aware timestamps for migration state tracking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix timezone inconsistency between migration_started_at and migration_completed_at: Schema Changes: - Change TIMESTAMP to TIMESTAMPTZ for migration_started_at and migration_completed_at - PostgreSQL stores timestamps in UTC and converts to local timezone on display - Ensures consistent timezone handling across all timestamp columns Code Changes: - Replace datetime.utcnow() with datetime.now(timezone.utc) - Use timezone-aware datetime objects for proper TIMESTAMPTZ handling - Import timezone module for UTC timezone support Impact: - Previous issue: migration_completed_at was 1 hour behind migration_started_at - Root cause: CURRENT_TIMESTAMP (local time) vs datetime.utcnow() (UTC naive) - Solution: Both columns now use TIMESTAMPTZ with timezone-aware datetimes Note: Existing migration_state records will have old TIMESTAMP format until table is altered: ALTER TABLE migration_state ALTER COLUMN migration_started_at TYPE TIMESTAMPTZ, ALTER COLUMN migration_completed_at TYPE TIMESTAMPTZ; 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/migrator/state_manager.py | 4 ++-- src/transformers/schema_transformer.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/migrator/state_manager.py b/src/migrator/state_manager.py index 90fd4d6..5b3a1e3 100644 --- a/src/migrator/state_manager.py +++ b/src/migrator/state_manager.py @@ -7,7 +7,7 @@ Tracks migration progress with: - status: pending, in_progress, completed """ from typing import Optional, Dict, Any -from datetime import datetime +from datetime import datetime, timezone import json from src.connectors.postgres_connector import PostgreSQLConnector @@ -199,7 +199,7 @@ class StateManager: if mark_completed: updates.append("migration_completed_at = %s") - params.append(datetime.utcnow()) + params.append(datetime.now(timezone.utc)) if status is None: updates.append("status = 'completed'") diff --git a/src/transformers/schema_transformer.py b/src/transformers/schema_transformer.py index 58a9da8..cc1a74d 100644 --- a/src/transformers/schema_transformer.py +++ b/src/transformers/schema_transformer.py @@ -183,8 +183,8 @@ CREATE TABLE IF NOT EXISTS migration_state ( table_name VARCHAR(255) NOT NULL, partition_name VARCHAR(255) NOT NULL, last_key JSONB, - migration_started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - migration_completed_at TIMESTAMP, + migration_started_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + migration_completed_at TIMESTAMPTZ, total_rows_migrated BIGINT DEFAULT 0, status VARCHAR(32) DEFAULT 'pending', PRIMARY KEY (table_name, partition_name),