Skip to content

sqlalchemy-spanner: Add native UUID type support #16605

@fgmacedo

Description

@fgmacedo

Hi there! Cloud Spanner added the native UUID column type in January 2026, but the sqlalchemy-spanner dialect does not recognize it yet. There is no entry in _type_map / _type_map_inv and no visit_UUID method in SpannerTypeCompiler.

In practice this means:

  • Column(sqlalchemy.Uuid) emits VARCHAR DDL instead of UUID
  • Reading a UUID column with sqlalchemy.Uuid fails with AttributeError: 'str' object has no attribute 'hex' because the driver returns strings but the SQLAlchemy Uuid type expects uuid.UUID objects
  • GENERATE_UUID() as column default is not recognized

Desired Code Experience

from sqlalchemy import Column, Uuid, create_engine
from sqlalchemy.orm import DeclarativeBase
import uuid

class Base(DeclarativeBase):
    pass

class MyTable(Base):
    __tablename__ = "my_table"
    id = Column(Uuid, primary_key=True, default=uuid.uuid4)
    ref_id = Column(Uuid, nullable=True)

This should:

  • Emit UUID in DDL (not VARCHAR)
  • Accept uuid.UUID objects on writes, converting to string for the Spanner API
  • Return uuid.UUID objects on reads, converting from string

Expected Results

CREATE TABLE my_table (
  id UUID NOT NULL,
  ref_id UUID,
) PRIMARY KEY (id)
row = session.get(MyTable, some_uuid)
assert isinstance(row.id, uuid.UUID)

API Client Information

sqlalchemy-spanner 1.14.0 (also verified against main branch / 1.17.2, neither has UUID support)

Use Case

We are building an Event Store on Cloud Spanner using UUID v4 as surrogate keys for aggregates and event IDs. The native UUID type stores 16 bytes internally (vs 36 bytes for STRING), provides built-in validation, and enables GENERATE_UUID() as server-side default. We currently work around this with a TypeDecorator wrapping String, but this prevents proper DDL emission and adds unnecessary indirection.

Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions