Skip to content

SQLAlchemy adapter: support SQLAlchemy 2.0 DeclarativeBase models and typed Select return #181

@jmartinhoj

Description

@jmartinhoj

Problem

The get_query function in the SQLAlchemy adapter has two related type-safety issues:

1. SQLAlchemy 2.0 DeclarativeBase not supported

SQLAlchemy 2.0 introduced a new base class DeclarativeBase (replacing the legacy declarative_base() / DeclarativeMeta approach). Models defined with the new style:

from sqlalchemy.orm import DeclarativeBase

class Base(DeclarativeBase):
    pass

class Resource(Base):
    __tablename__ = "resource"
    id: Mapped[int] = mapped_column(primary_key=True)

...do not inherit from DeclarativeMeta, so passing them as table to get_query currently raises an error on type checkers.

2. Bare Select return type loses type information

The return type is currently annotated as Select (unparameterised), which loses row-type information. Callers cannot benefit from type inference on query results.

Proposed fix

  • Try-import DeclarativeBase from sqlalchemy.orm (available in SQLAlchemy ≥ 2.0), falling back to a placeholder class for 1.4 compatibility, and include type[DeclarativeBase] in GenericTable.
  • Add @overload signatures for get_query so that when an ORM model class is passed, the return type resolves to Select[Tuple[T]], and when a core Table is passed it returns Select[Any].
  • Add from __future__ import annotations to keep the subscripted Select[...] syntax compatible with Python 3.8/SQLAlchemy 1.4.

I have a working patch ready and am happy to submit a PR once there is agreement on the approach.

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