From 1a6ba7a5f1fc2a3bd5ec793ececb8aca2bee3a8b Mon Sep 17 00:00:00 2001 From: Arif Dogan Date: Tue, 11 Nov 2025 02:44:03 +0100 Subject: [PATCH] fix: use timezone-aware datetimes in all DateTime columns (fixes #34) --- fastapi_radar/__init__.py | 2 +- fastapi_radar/models.py | 28 +++++++++++++++------------- pyproject.toml | 2 +- radar.duckdb | Bin 8663040 -> 8663040 bytes setup.py | 2 +- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/fastapi_radar/__init__.py b/fastapi_radar/__init__.py index bf15b24..27cadb1 100644 --- a/fastapi_radar/__init__.py +++ b/fastapi_radar/__init__.py @@ -3,5 +3,5 @@ from .radar import Radar from .background import track_background_task -__version__ = "0.3.2" +__version__ = "0.3.3" __all__ = ["Radar", "track_background_task"] diff --git a/fastapi_radar/models.py b/fastapi_radar/models.py index f8e30a5..5de4b8a 100644 --- a/fastapi_radar/models.py +++ b/fastapi_radar/models.py @@ -41,7 +41,7 @@ class CapturedRequest(Base): duration_ms = Column(Float) client_ip = Column(String(50)) created_at = Column( - DateTime, default=lambda: datetime.now(timezone.utc), index=True + DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), index=True ) queries = relationship( @@ -71,7 +71,7 @@ class CapturedQuery(Base): rows_affected = Column(Integer) connection_name = Column(String(100)) created_at = Column( - DateTime, default=lambda: datetime.now(timezone.utc), index=True + DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), index=True ) request = relationship( @@ -92,7 +92,7 @@ class CapturedException(Base): exception_value = Column(Text) traceback = Column(Text, nullable=False) created_at = Column( - DateTime, default=lambda: datetime.now(timezone.utc), index=True + DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), index=True ) request = relationship( @@ -111,15 +111,15 @@ class Trace(Base): service_name = Column(String(100), index=True) operation_name = Column(String(200)) start_time = Column( - DateTime, default=lambda: datetime.now(timezone.utc), index=True + DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), index=True ) - end_time = Column(DateTime) + end_time = Column(DateTime(timezone=True)) duration_ms = Column(Float) span_count = Column(Integer, default=0) status = Column(String(20), default="ok") tags = Column(JSON) created_at = Column( - DateTime, default=lambda: datetime.now(timezone.utc), index=True + DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), index=True ) spans = relationship( @@ -139,14 +139,14 @@ class Span(Base): operation_name = Column(String(200), nullable=False) service_name = Column(String(100), index=True) span_kind = Column(String(20), default="server") - start_time = Column(DateTime, nullable=False, index=True) - end_time = Column(DateTime) + start_time = Column(DateTime(timezone=True), nullable=False, index=True) + end_time = Column(DateTime(timezone=True)) duration_ms = Column(Float) status = Column(String(20), default="ok") tags = Column(JSON) logs = Column(JSON) created_at = Column( - DateTime, default=lambda: datetime.now(timezone.utc), index=True + DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), index=True ) trace = relationship( @@ -166,7 +166,9 @@ class SpanRelation(Base): parent_span_id = Column(String(16), index=True) child_span_id = Column(String(16), index=True) depth = Column(Integer, default=0) - created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) + created_at = Column( + DateTime(timezone=True), default=lambda: datetime.now(timezone.utc) + ) class BackgroundTask(Base): @@ -181,10 +183,10 @@ class BackgroundTask(Base): status = Column( String(20), default="pending", index=True ) # pending, running, completed, failed - start_time = Column(DateTime, index=True) - end_time = Column(DateTime) + start_time = Column(DateTime(timezone=True), index=True) + end_time = Column(DateTime(timezone=True)) duration_ms = Column(Float) error = Column(Text) created_at = Column( - DateTime, default=lambda: datetime.now(timezone.utc), index=True + DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), index=True ) diff --git a/pyproject.toml b/pyproject.toml index 95aae4c..814304c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "fastapi-radar" -version = "0.3.2" +version = "0.3.3" description = "A debugging dashboard for FastAPI applications with real-time monitoring" readme = "README.md" requires-python = ">=3.9" diff --git a/radar.duckdb b/radar.duckdb index 28e46609f83a4b90b16445d242e3f18d64d1ddc2..a1dc38076b487a4b4f9d40a4d7374f25914f080e 100644 GIT binary patch delta 5301 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 NA&&4i!XAWo{sSehp%MT9 diff --git a/setup.py b/setup.py index 5b46065..f44f727 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setup( name="fastapi-radar", - version="0.3.2", + version="0.3.3", author="Arif Dogan", author_email="me@arif.sh", description=(