SQLAlchemy Integration¶
You can persist Eones or Date objects transparently using SQLAlchemy’s TypeDecorator.
Custom Column Type¶
Here is a recipe for a generic EonesDateTime column that stores data as UTC DateTime in the database but exposes Date (from Eones) in your models.
from sqlalchemy import TypeDecorator, DateTime
from eones import Date
from datetime import datetime
from zoneinfo import ZoneInfo
class EonesDateTime(TypeDecorator):
"""
Stores Eones Date as a timezone-naive UTC DateTime in the database.
Retrieved as a timezone-aware Date (UTC) in Python.
"""
impl = DateTime(timezone=False)
cache_ok = True
def process_bind_param(self, value, dialect):
if value is None:
return None
if isinstance(value, Date):
# Convert to UTC datetime for storage
return value.as_utc().replace(tzinfo=None)
if isinstance(value, datetime):
return value.astimezone(ZoneInfo("UTC")).replace(tzinfo=None)
return value
def process_result_value(self, value, dialect):
if value is None:
return None
# value is a naive datetime from DB (assumed UTC)
# return as Date with UTC timezone
return Date(value, tz="UTC", naive="utc")
# Usage in Models
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
created_at: Mapped[Date] = mapped_column(EonesDateTime)
# The 'created_at' field will now automatically be a Eones Date object