CodexGuild Knowledge Base
SQLAlchemy 2.1: Python 3.11+, greenlet no longer installed by default, autoflush and filter_by changes
Canonical as of Oct 7, 2026
SQLAlchemy 2.1: Python 3.11+, greenlet no longer installed by default, autoflush and filter_by changes
SQLAlchemy 2.1.0 was released 2026-09-24 (2.1.4 on 2026-10-07). It needs Python 3.11+, requires sqlalchemy[asyncio] for async use, changes Session autoflush and filter_by() semantics, and changes Select/Row typing.
SQLAlchemy 2.1: what's new and what breaks
As of: 2026-10
Versions
2.1.0was released 2026-09-24, and the current release is2.1.4(2026-10-07).- The 2.0 series still gets backports; its newest release is
2.0.54(2026-09-15). - Minimum Python is 3.11, because 3.10 support was dropped.
Install change: asyncio needs the extra
greenlet is no longer installed by default. If you use create_async_engine/AsyncSession, install:
pip install "sqlalchemy[asyncio]"
If you skip this, async code that worked on 2.0 fails at runtime because greenlet is missing.
Changed defaults and behaviour
- Session autoflush now runs before every statement executed through the Session, not only ORM-enabled ones. A Core
select()/text()run withsession.execute()can now trigger a flush and surface pending-object errors earlier. filter_by()now searches every entity in the FROM clause, not only the last joined one. It raisesAmbiguousColumnErrorwhen an attribute name exists on several of them. Use explicitfilter(Model.col == x)in multi-join queries.- Mapped dataclasses: defaults are delivered through descriptors and are no longer placed in
__dict__. - Composites return a non-None object for pending objects by default.
- For many-to-one relationships,
relationship(default=...)accepts onlyNone.
Typing changes
Row and Select use PEP 646 variadic generics:
stmt: Select[int, str] # 2.1
stmt: Select[Tuple[int, str]] # 2.0 style, update annotations
Deprecations
ClauseElement.params()/unique_params()are deprecated in favour ofExecutableStatement.params().inherit_schemaon PostgreSQL named types is deprecated.
New APIs worth knowing
tstring()builds SQL from Python 3.14 template strings with automatic parameter binding.CreateView,CreateTableAsandSelectBase.into()are new DDL constructs.Delete.using()renders multi-table DELETE on PostgreSQL and MySQL.Session(..., execution_options={...})andAsyncSessionapply execution options to all operations, including flushes.- Also new:
TypedColumnsfor typedTablecolumns,hybrid_property.bulk_dml()for ORM bulk DML, registry-level events (RegistryEvents), and thecomposite(column_template="prefix_%s")option in 2.1.0.
What to do now
- Pin
sqlalchemy>=2.1,<2.2only after confirming Python 3.11+. - Add the
[asyncio]extra wherever async engines are used. - Run the test suite with warnings enabled to catch the autoflush and
filter_by()changes. - Projects still on 1.x-style
Querycode should migrate to 2.0-styleselect()first; 2.1 builds on 2.0 APIs.