Basic Types¶
Core SQLAlchemy types for common data patterns across database backends.
GUID¶
Platform-independent UUID/GUID type with automatic dialect adaptation.
Characteristics:
Python type:
uuid.UUIDStorage format varies by database dialect
Accepts UUID objects, hex strings, or bytes
Returns Python
uuid.UUIDobjects
Database-Specific Storage¶
Database |
Storage Type |
|---|---|
PostgreSQL, DuckDB, CockroachDB |
Native UUID type |
Microsoft SQL Server |
UNIQUEIDENTIFIER |
Oracle |
RAW(16) - 16 bytes binary |
SQLite, MySQL, others |
BINARY(16) or CHAR(32) depending on configuration |
Basic Usage¶
from uuid import UUID, uuid4
from sqlalchemy.orm import Mapped, mapped_column
from advanced_alchemy.base import DefaultBase
from advanced_alchemy.types import GUID
class User(DefaultBase):
__tablename__ = "users"
id: "Mapped[UUID]" = mapped_column(GUID, primary_key=True, default=uuid4)
email: "Mapped[str]" = mapped_column(unique=True)
Binary vs String Storage¶
Control storage format on databases that don’t have native UUID:
# Binary storage (default, more efficient)
id: "Mapped[UUID]" = mapped_column(GUID(binary=True), primary_key=True)
# String storage (32 hex characters)
id: "Mapped[UUID]" = mapped_column(GUID(binary=False), primary_key=True)
Creating Records¶
from uuid import uuid4
from sqlalchemy.ext.asyncio import AsyncSession
async def create_user(session: AsyncSession) -> User:
user = User(
id=uuid4(), # Explicit UUID
email="user@example.com",
)
session.add(user)
await session.commit()
return user
# Or let default handle it
async def create_user_auto(session: AsyncSession) -> User:
user = User(email="user@example.com") # UUID generated automatically
session.add(user)
await session.commit()
return user
Querying¶
from uuid import UUID
async def get_user(session: AsyncSession, user_id: UUID) -> "Optional[User]":
stmt = select(User).where(User.id == user_id)
result = await session.execute(stmt)
return result.scalar_one_or_none()
# Works with string input too
async def get_user_str(session: AsyncSession, user_id: str) -> "Optional[User]":
stmt = select(User).where(User.id == UUID(user_id))
result = await session.execute(stmt)
return result.scalar_one_or_none()
Integration with Base Classes¶
Advanced Alchemy base classes handle GUID automatically:
from advanced_alchemy.base import UUIDBase, UUIDAuditBase
# Minimal setup - just define your fields
class Product(UUIDBase):
__tablename__ = "products"
name: "Mapped[str]"
price: "Mapped[float]"
# With audit columns
class Order(UUIDAuditBase):
__tablename__ = "orders"
product_id: "Mapped[UUID]" = mapped_column(GUID)
quantity: "Mapped[int]"
DateTimeUTC¶
Timezone-aware datetime type that ensures UTC storage and returns timezone-aware Python datetime objects.
Characteristics:
Python type:
datetime.datetimeStorage: UTC timezone
Input requirement: Timezone-aware datetime
Output: Timezone-aware datetime (UTC)
Basic Usage¶
from datetime import datetime, timezone
from sqlalchemy.orm import Mapped, mapped_column
from advanced_alchemy.base import DefaultBase
from advanced_alchemy.types import DateTimeUTC
class Event(DefaultBase):
__tablename__ = "events"
name: "Mapped[str]"
scheduled_at: "Mapped[datetime]" = mapped_column(DateTimeUTC)
created_at: "Mapped[datetime]" = mapped_column(
DateTimeUTC,
default=lambda: datetime.now(timezone.utc)
)
from datetime import datetime, UTC
from sqlalchemy.orm import Mapped, mapped_column
from advanced_alchemy.base import DefaultBase
from advanced_alchemy.types import DateTimeUTC
class Event(DefaultBase):
__tablename__ = "events"
name: "Mapped[str]"
scheduled_at: "Mapped[datetime]" = mapped_column(DateTimeUTC)
created_at: "Mapped[datetime]" = mapped_column(
DateTimeUTC,
default=lambda: datetime.now(UTC)
)
Creating Records¶
from datetime import datetime, timezone
async def create_event(session: AsyncSession) -> Event:
# Timezone-aware datetime required
event = Event(
name="Product Launch",
scheduled_at=datetime.now(timezone.utc)
)
session.add(event)
await session.commit()
return event
# Error: naive datetime not allowed
async def create_event_error(session: AsyncSession) -> Event:
event = Event(
name="Meeting",
scheduled_at=datetime.now() # TypeError: tzinfo is required
)
session.add(event)
await session.commit()
return event
from datetime import datetime, UTC
async def create_event(session: AsyncSession) -> Event:
# Timezone-aware datetime required
event = Event(
name="Product Launch",
scheduled_at=datetime.now(UTC)
)
session.add(event)
await session.commit()
return event
# Error: naive datetime not allowed
async def create_event_error(session: AsyncSession) -> Event:
event = Event(
name="Meeting",
scheduled_at=datetime.now() # TypeError: tzinfo is required
)
session.add(event)
await session.commit()
return event
Timezone Conversion¶
Input datetimes are automatically converted to UTC:
from datetime import datetime
from zoneinfo import ZoneInfo
# Create event with Eastern time
eastern_time = datetime(2025, 10, 18, 14, 30, tzinfo=ZoneInfo("America/New_York"))
event = Event(
name="Regional Meeting",
scheduled_at=eastern_time # Stored as UTC in database
)
# Retrieved datetime is in UTC
await session.commit()
await session.refresh(event)
print(event.scheduled_at) # 2025-10-18 18:30:00+00:00 (UTC)
Integration with Base Classes¶
Audit base classes include DateTimeUTC automatically:
from advanced_alchemy.base import UUIDAuditBase
class Document(UUIDAuditBase):
__tablename__ = "documents"
title: "Mapped[str]"
# created_at and updated_at are DateTimeUTC, added automatically
# Access audit timestamps
doc = Document(title="Report")
await session.add(doc)
await session.commit()
print(doc.created_at) # Timezone-aware UTC datetime
print(doc.updated_at) # Timezone-aware UTC datetime
JsonB¶
Efficient JSON storage type that uses native binary JSON where available.
Characteristics:
PostgreSQL/CockroachDB: Native JSONB (binary JSON)
Oracle: BLOB with JSON constraint
Other databases: Standard JSON type
Basic Usage¶
from typing import Any
from sqlalchemy.orm import Mapped, mapped_column
from advanced_alchemy.base import UUIDBase
from advanced_alchemy.types import JsonB
class UserSettings(UUIDBase):
__tablename__ = "user_settings"
user_id: "Mapped[UUID]" = mapped_column(GUID)
preferences: "Mapped[dict[str, Any]]" = mapped_column(JsonB)
tags: "Mapped[list[str]]" = mapped_column(JsonB)
Storing Complex Data¶
async def create_settings(session: AsyncSession) -> UserSettings:
settings = UserSettings(
user_id=user.id,
preferences={
"theme": "dark",
"language": "en",
"notifications": {
"email": True,
"push": False,
},
},
tags=["premium", "verified"],
)
session.add(settings)
await session.commit()
return settings
Querying JSON Data¶
PostgreSQL JSON operators:
from sqlalchemy import select
# PostgreSQL JSONB operators
async def find_dark_theme_users(session: AsyncSession) -> "list[UserSettings]":
stmt = select(UserSettings).where(
UserSettings.preferences["theme"].astext == "dark"
)
result = await session.execute(stmt)
return list(result.scalars())
# Check if key exists
async def find_with_notifications(session: AsyncSession) -> "list[UserSettings]":
stmt = select(UserSettings).where(
UserSettings.preferences["notifications"].isnot(None)
)
result = await session.execute(stmt)
return list(result.scalars())
Updating JSON Data¶
async def update_preference(
session: AsyncSession,
settings: UserSettings,
key: str,
value: Any
) -> UserSettings:
# Modify the dictionary
settings.preferences[key] = value
# SQLAlchemy tracks changes
await session.commit()
return settings
# Or replace entirely
async def replace_preferences(
session: AsyncSession,
settings: UserSettings
) -> UserSettings:
settings.preferences = {
"theme": "light",
"language": "es",
}
await session.commit()
return settings
BigIntIdentity¶
BigInteger type that automatically falls back to Integer for SQLite.
Characteristics:
Python type:
intMost databases: BIGINT (8 bytes, ±9 quintillion)
SQLite: INTEGER (SQLite integers are always 64-bit)
Typically used for auto-incrementing primary keys
Basic Usage¶
from sqlalchemy.orm import Mapped, mapped_column
from advanced_alchemy.base import DefaultBase
from advanced_alchemy.types import BigIntIdentity
class Product(DefaultBase):
__tablename__ = "products"
id: "Mapped[int]" = mapped_column(BigIntIdentity, primary_key=True)
sku: "Mapped[str]" = mapped_column(unique=True)
name: "Mapped[str]"
Integration with Base Classes¶
BigInt base classes use this type automatically:
from advanced_alchemy.base import BigIntBase, BigIntAuditBase
# Minimal setup
class Article(BigIntBase):
__tablename__ = "articles"
title: "Mapped[str]"
content: "Mapped[str]"
# With audit columns
class Comment(BigIntAuditBase):
__tablename__ = "comments"
article_id: "Mapped[int]" = mapped_column(BigIntIdentity)
content: "Mapped[str]"
See Also¶
Security Types - Encrypted and password types
File Storage - File object storage
Modeling - Base class integration
types - Complete API reference