Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion psqlpy_sqlalchemy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

PsqlpyDialect = PSQLPyAsyncDialect

__version__ = "0.1.1b1"
__version__ = "0.1.1b2"
__all__ = ["PsqlpyDialect", "PSQLPyAsyncDialect"]
1 change: 1 addition & 0 deletions psqlpy_sqlalchemy/dialect.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ class PSQLPyAsyncDialect(PGDialect):
sqltypes.SmallInteger: _PGSmallInteger,
sqltypes.BigInteger: _PGBigInteger,
sqltypes.Boolean: _PGBoolean,
sqltypes.Uuid: _PGUUID, # Uuid type (lowercase) inferred from Mapped[uuid.UUID]
UUID: _PGUUID, # UUID support with proper parameter binding
# Note: NullType mapping removed - standard PostgreSQL dialect doesn't map it
# and mapping it with render_bind_cast=True causes DDL compilation errors
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "psqlpy-sqlalchemy"
version = "0.1.1b1"
version = "0.1.1b2"
description = "SQLAlchemy dialect for psqlpy PostgreSQL driver"
readme = "README.md"
license = {text = "MIT"}
Expand Down
56 changes: 55 additions & 1 deletion tests/test_uuid_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.exc import StatementError
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import DeclarativeBase, sessionmaker
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, sessionmaker


# Skip tests if database is not available (check for CI environment or explicit flag)
Expand Down Expand Up @@ -357,6 +357,60 @@ async def test_uuid_select_full_row(self, session):
assert isinstance(row.uid, uuid.UUID)
assert row.uid == test_uuid

async def test_uuid_mapped_annotation_without_explicit_as_uuid(
self, engine
):
"""Test that Mapped[uuid.UUID] without explicit UUID(as_uuid=True) returns uuid.UUID objects.

This test verifies the exact pattern:
id: Mapped[uuid.UUID] = mapped_column(primary_key=True)

When using SQLAlchemy 2.0+ Mapped annotations with Python's uuid.UUID type,
the dialect should automatically return uuid.UUID objects, not strings.
"""
from sqlalchemy import select

# Create a model using the Mapped[uuid.UUID] annotation pattern
class SimplifiedUUIDModel(Base):
__tablename__ = "test_simplified_uuid"

id: Mapped[uuid.UUID] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(100))

# Create table
async with engine.begin() as conn:
await conn.run_sync(
SimplifiedUUIDModel.__table__.create, checkfirst=True
)

try:
# Create session
async_session = sessionmaker(engine, class_=AsyncSession)
async with async_session() as session:
# Insert test data
test_uuid = uuid.uuid4()
obj = SimplifiedUUIDModel(id=test_uuid, name="test")
session.add(obj)
await session.commit()

# Select using the exact pattern from the issue
stmt = select(SimplifiedUUIDModel.id)
result = (await session.scalars(stmt)).all()

# Critical assertion: should be uuid.UUID, not str
assert len(result) == 1
assert isinstance(result[0], uuid.UUID), (
f"Expected uuid.UUID but got {type(result[0]).__name__}. "
f"This means the Mapped[UUID] pattern is returning strings instead of UUID objects."
)
assert result[0] == test_uuid
finally:
# Clean up
async with engine.begin() as conn:
await conn.run_sync(
SimplifiedUUIDModel.__table__.drop, checkfirst=True
)


class TestUUIDTypeCompatibility:
"""Test UUID type compatibility with existing functionality."""
Expand Down