]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/log
thirdparty/sqlalchemy/sqlalchemy.git
3 hours agoMerge "user_defined_options returns memoized options" into main main
Michael Bayer [Sat, 23 May 2026 01:32:16 +0000 (01:32 +0000)] 
Merge "user_defined_options returns memoized options" into main

31 hours agouser_defined_options returns memoized options
Federico Caselli [Tue, 19 May 2026 21:39:49 +0000 (23:39 +0200)] 
user_defined_options returns memoized options

Updated the attribute :attr:`_orm.ORMExecuteState.user_defined_options` to
include options that were added to the statement before calling
:meth:`.Select.with_only_columns` or :meth:`_orm.Query.with_entities`.

Fixes: #13309
Change-Id: Ie6e3f46662542010f4d524820ae697638f36d459

2 days agoMerge "Fix ExcludeConstraint not forwarding info to parent constructor" into main
Michael Bayer [Wed, 20 May 2026 21:02:33 +0000 (21:02 +0000)] 
Merge "Fix ExcludeConstraint not forwarding info to parent constructor" into main

2 days agoMerge "implement _post_inspect for AliasedInsp" into main
Michael Bayer [Wed, 20 May 2026 21:02:02 +0000 (21:02 +0000)] 
Merge "implement _post_inspect for AliasedInsp" into main

2 days agoimplement _post_inspect for AliasedInsp
Mike Bayer [Wed, 20 May 2026 19:59:10 +0000 (15:59 -0400)] 
implement _post_inspect for AliasedInsp

Fixed issue where using :func:`_orm.with_polymorphic` on a leaf class (a
subclass with no further descendants) or a non-inherited class would fail
with an ``AttributeError`` when used in an ORM statement, due to
:func:`_orm.configure_mappers` not being triggered implicitly. The fix
ensures that :class:`.AliasedInsp` participates in the ``_post_inspect``
hook, triggering mapper configuration during ORM statement compilation.

Fixes: #13319
Change-Id: Ic5910474676be41f8c815dc72c38fca8e20cdeb9

2 days agoFix ExcludeConstraint not forwarding info to parent constructor
WiktorB2004 [Wed, 20 May 2026 20:05:41 +0000 (16:05 -0400)] 
Fix ExcludeConstraint not forwarding info to parent constructor

Fixed issue where the :class:`.ExcludeConstraint` construct did not
correctly forward the :paramref:`.ExcludeConstraint.info` parameter to
the superclass, causing user-defined metadata to be lost. Pull request
courtesy Wiktor Byrka.

Fixes: #13317
Closes: #13316
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13316
Pull-request-sha: be7f4fee2c40d1986519e93145471faad61021af
Change-Id: Idc4846f02127d1d39a8c638cb03b0379932e9fd6

2 days agoMerge "Fix joinedload + of_type() + and_() invalid SQL for subclass columns" into...
Michael Bayer [Wed, 20 May 2026 20:02:35 +0000 (20:02 +0000)] 
Merge "Fix joinedload + of_type() + and_() invalid SQL for subclass columns" into main

2 days agoMerge "Fix floordiv (//) for float/numeric by int with div_is_floordiv dialects"...
Michael Bayer [Wed, 20 May 2026 19:53:18 +0000 (19:53 +0000)] 
Merge "Fix floordiv (//) for float/numeric by int with div_is_floordiv dialects" into main

2 days agoFix joinedload + of_type() + and_() invalid SQL for subclass columns
Joaquin Hui Gomez [Wed, 1 Apr 2026 17:29:38 +0000 (13:29 -0400)] 
Fix joinedload + of_type() + and_() invalid SQL for subclass columns

Fixed issue where using :func:`_orm.joinedload` with
:meth:`.PropComparator.of_type` targeting a joined-table subclass combined
with :meth:`.PropComparator.and_` referencing a column on that subclass
would generate invalid SQL, where the subclass column was not adapted to
the subquery alias.  Pull request courtesy Joaquin Hui Gomez.

Fixes #13203

Closes: #13206
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13206
Pull-request-sha: ba55b0c3e2a8dae28a1c7d7ae646e3480a04425c

Change-Id: I78fe4672649d1d5498e3bc653e5d943ccb55dafd

2 days agoFix floordiv (//) for float/numeric by int with div_is_floordiv dialects
OSS Contributor [Mon, 23 Mar 2026 14:44:40 +0000 (10:44 -0400)] 
Fix floordiv (//) for float/numeric by int with div_is_floordiv dialects

Fixed issue where floor division (``//``) between a :class:`.Float` or
:class:`.Numeric` numerator and an :class:`.Integer` denominator would omit
the ``FLOOR()`` SQL wrapper on dialects where
:attr:`.Dialect.div_is_floordiv` is ``True`` (the default, including
PostgreSQL and SQLite).  ``FLOOR()`` is now applied if either the
denominator or the numerator is a non-integer, so that expressions such as
``float_col // int_col`` render as ``FLOOR(float_col / int_col)`` instead
of the incorrect ``float_col / int_col``.  Pull request courtesy r266-tech.

Fixes: #10528
Closes: #13191
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13191
Pull-request-sha: c9cbc47c877e19c91f912556b4ead6cd26e3cfe6

Change-Id: I5f9f02d966aa6ccee214a2c5cc27a73a4292da03

2 days agoFix trivial PyPy failures
mattip [Wed, 20 May 2026 17:47:17 +0000 (13:47 -0400)] 
Fix trivial PyPy failures

<!-- Provide a general summary of your proposed changes in the Title field above -->

### Description

Fixes: #13274
References: #9154

There were two relatively causes to some of the ~21 failures on PyPy:
- weakrefs may be deleted but the objects not finalized on PyPy. This manifests as `ref.obj() is None` I added a test for the `release()` case that also failed on CPython before the fix.
- a condition added in 2022 for missing sqllite3 behaviour is no longer necessary, and is now causing a failure

In order to run the changes in CI, I added PyPy to the PR CI run. Before merging I will revert that change. There are still a number of failures with PyPy around different error messages, different inspect.signatures and one sticky problem with the pure-python datetime.py that actually comes from CPython. I will continue to work on them, but they are not specific to sqlalchemy.

Note the CI run is ~6 minutes where the CPython ones are ~3 minutes. This is expected, since PyPy's JIT does not kick in on short tests, and the base compiler is about 2x slower.

### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)

-->

This pull request is:

- [ ] A documentation / typographical / small typing error fix
- Good to go, no issue or tests are needed
- [x] A short code fix
- please include the issue number, and create an issue if none exists, which
  must include a complete example of the issue.  one line code fixes without an
  issue and demonstration will not be accepted.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.   one line code fixes without tests will not be accepted.
- [ ] A new feature implementation
- please include the issue number, and create an issue if none exists, which must
  include a complete example of how the feature would look.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.

**Have a nice day!**

Closes: #13276
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13276
Pull-request-sha: 00472f32f64827325f071150e8b6ecf1fbe9f22e

Change-Id: Id5d4ba37cf8db2345a948f973d7b1710910359a1

2 days agoMerge "document postgresql_nulls_not_distinct" into main
Michael Bayer [Wed, 20 May 2026 14:05:36 +0000 (14:05 +0000)] 
Merge "document postgresql_nulls_not_distinct" into main

3 days agoAdjust TypeError message to Python 3.15
Karolina Surma [Tue, 19 May 2026 14:20:38 +0000 (10:20 -0400)] 
Adjust TypeError message to Python 3.15

<!-- Provide a general summary of your proposed changes in the Title field above -->

### Description
The `.fromisoformat()` error message tested in `test_no_string()` changed in Python 3.15, this fixes the test.

See #13308 for the `rel_2_0` branch.

### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)

-->

This pull request is:

- [ ] A documentation / typographical / small typing error fix
- Good to go, no issue or tests are needed
- [x] A short code fix (in a test, therefore I didn’t create an issue)
- please include the issue number, and create an issue if none exists, which
  must include a complete example of the issue.  one line code fixes without an
  issue and demonstration will not be accepted.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.   one line code fixes without tests will not be accepted.
- [ ] A new feature implementation
- please include the issue number, and create an issue if none exists, which must
  include a complete example of how the feature would look.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.

**Have a nice day!**

Closes: #13307
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13307
Pull-request-sha: 90bc13fc416ea45ba5429d5f8ecffc24b108c1b1

Change-Id: I461d71b0fad18fa4f108102bb1c22c0e980fc70e

3 days agorobustly handle reconnect param across all pymysql variants
Mike Bayer [Tue, 19 May 2026 13:40:01 +0000 (09:40 -0400)] 
robustly handle reconnect param across all pymysql variants

Fixed issue in aiomysql and asyncmy dialects that appears as of using
pymysql 1.2.0; the dialects were not properly taking into account logic
that detects the argument signature of pymysql's ``ping()`` method which
was added as part of :ticket:`10492`.

We add a "does ping have reconnect" check for all three DBAPIs
individually.  To suit asyncmy's use of cython we also needed to
adjust vendored getargspec() routines.

Fixes: #13306
Change-Id: Iad90ec6cfe9ee3b99736dd2153264090e7f76be1

4 days agoMerge "Postgresql default to no backslash escaping" into main
Michael Bayer [Mon, 18 May 2026 16:31:37 +0000 (16:31 +0000)] 
Merge "Postgresql default to no backslash escaping" into main

4 days agoMerge "resolve table names using MetaData.schema default in declarative registry...
Michael Bayer [Mon, 18 May 2026 16:11:48 +0000 (16:11 +0000)] 
Merge "resolve table names using MetaData.schema default in declarative registry" into main

4 days agoresolve table names using MetaData.schema default in declarative registry
Mike Bayer [Thu, 30 Apr 2026 19:13:39 +0000 (15:13 -0400)] 
resolve table names using MetaData.schema default in declarative registry

Also resolved class-level MetaData not being consulted by the
declarative class registry when resolving string-based table
references.  The registry now uses the same metadata resolution
logic as table creation, checking for a class-specific ``metadata``
attribute before falling back to ``registry.metadata``.  The
``_metadata_for_cls`` function was factored into ``orm/util.py``
for shared use by both ``decl_base.py`` and ``clsregistry.py``.

Fixes: #8068
Fixes: #13291
Change-Id: Ib846be0267f9295a5fee945dc6cf0a72c237bd2c

4 days agoMerge "Block Result.unique() with Result.yield_per() for ORM results" into main
Michael Bayer [Mon, 18 May 2026 12:24:26 +0000 (12:24 +0000)] 
Merge "Block Result.unique() with Result.yield_per() for ORM results" into main

5 days agodocument postgresql_nulls_not_distinct
David Lord [Sun, 17 May 2026 20:09:16 +0000 (16:09 -0400)] 
document postgresql_nulls_not_distinct

<!-- Provide a general summary of your proposed changes in the Title field above -->

### Description
<!-- Describe your changes in detail -->

https://github.com/sqlalchemy/sqlalchemy/issues/8240 and https://github.com/sqlalchemy/sqlalchemy/pull/9834 added support for `NULLS NOT DISTINCT` to the PostgreSQL dialect, but didn't add it to the docs (only the change log). This adds a section to the "Constraint Options" section of the PostgreSQL dialect docs.

### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)

-->

This pull request is:

- [x] A documentation / typographical / small typing error fix
- Good to go, no issue or tests are needed
- [ ] A short code fix
- please include the issue number, and create an issue if none exists, which
  must include a complete example of the issue.  one line code fixes without an
  issue and demonstration will not be accepted.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.   one line code fixes without tests will not be accepted.
- [ ] A new feature implementation
- please include the issue number, and create an issue if none exists, which must
  include a complete example of how the feature would look.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.

**Have a nice day!**

Closes: #13279
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13279
Pull-request-sha: cdc858cd88fbf86661662147210f9587117aa593

Change-Id: I3f2c8fe346d3235fa8ba12c4d9ab712ddb840230

5 days agoadd update to black 26.3.1 commit to blame ignore
Federico Caselli [Sun, 17 May 2026 20:05:26 +0000 (22:05 +0200)] 
add update to black 26.3.1 commit to blame ignore

Change-Id: I98dbccf0b60d7672627736bbc20a7a6a27fba22a

5 days agoremove redundant deserializer assignment from asyncpg dialect (#13287)
Henry Cai [Sun, 17 May 2026 20:02:37 +0000 (13:02 -0700)] 
remove redundant deserializer assignment from asyncpg dialect (#13287)

10 days agoBlock Result.unique() with Result.yield_per() for ORM results
Mike Bayer [Tue, 12 May 2026 18:30:37 +0000 (14:30 -0400)] 
Block Result.unique() with Result.yield_per() for ORM results

The unique() + yield_per combination was only blocked when yield_per
was set via execution_options(yield_per=N); calling these as methods
on the result (e.g. result.unique().yield_per(N)) bypassed the check
and silently produced incorrect results.

Restructured _unique_filters on SimpleResultMetaData to be a callable
_create_unique_filters that receives the Result, allowing it to check
the yield_per state regardless of how it was activated.

Fixes: #13293
Change-Id: I7e6a5e5b2e1d4c8f9a0b3d6e7f1c2a4d5b8e9f0a

10 days agoMerge "populate existing can be in exec option in session.get" into main
Michael Bayer [Tue, 12 May 2026 13:03:37 +0000 (13:03 +0000)] 
Merge "populate existing can be in exec option in session.get" into main

12 days agoupdate to black 26.3.1
Federico Caselli [Fri, 8 May 2026 20:48:58 +0000 (22:48 +0200)] 
update to black 26.3.1

Closes: #13280
Change-Id: Ifbb77dd6d2a1c228ae97fcf8160f40e975edc57c

12 days agopopulate existing can be in exec option in session.get
Federico Caselli [Wed, 29 Apr 2026 21:09:57 +0000 (23:09 +0200)] 
populate existing can be in exec option in session.get

The ``populate_existing`` execution option is now honored when passed
in the :paramref:`.Session.get.execution_options` dict by the method
:meth:`.Session.get` and analogous in other session kinds. The current
:paramref:`.Session.get.populate_existing` parameter will takes precedence
if specified, overriding the value of the execution options.

Fixes: #10610
Change-Id: I4ddc9a7c6dda8f31f4dd413b49a9196efb3edaa6

12 days agocollect pep8 errors
Mike Bayer [Sun, 10 May 2026 15:30:00 +0000 (11:30 -0400)] 
collect pep8 errors

run each command in a try/except (they print out error messages
regardless) and report at the end on all individual runs.

Change-Id: I347c04f5c49c69daadf9f5f9e7c6c488cdf27f35

2 weeks agoAdd sqlite.JSONB type for binary JSON storage (SQLite >= 3.45.0)
Shamil Abdulaev [Tue, 28 Apr 2026 11:23:14 +0000 (07:23 -0400)] 
Add sqlite.JSONB type for binary JSON storage (SQLite >= 3.45.0)

Added :class:`_sqlite.JSONB` type for SQLite's binary JSON storage
format, available as of SQLite version 3.45.0. Values are stored via
the ``jsonb()`` SQL function and retrieved via ``json()``, while the
Python-side behavior remains identical to :class:`_sqlite.JSON`.
Pull request courtesy Shamil Abdulaev.

Fixes: #13260
Adds `sqlalchemy.dialects.sqlite.JSONB` — a new dialect-specific type
for SQLite's binary JSON storage format, introduced in SQLite 3.45.0.

The type:
- renders `JSONB` in DDL (`CREATE TABLE t (col JSONB)`)
- wraps bind values with `jsonb()` on write, storing data as a BLOB
- wraps column reads with `json()`, returning standard text JSON to Python
- reflects back from the database as `sqlite.JSONB`
- behaves identically to `sqlite.JSON` on the Python side

SQLite 3.45.0 introduced a native binary JSON format (JSONB) that is
more compact and faster to parse than text JSON. Users who want to opt
into this storage format had no way to do so via SQLAlchemy.

- `JSONB` inherits from `sqlite.JSON` and defines `__visit_name__ = "JSONB"`
  so the DDL compiler dispatches to `visit_JSONB` instead of `visit_JSON`
- Added `JSONB: JSONB` to `colspecs` so the type is not remapped to
  `_SQliteJson` via the `sqltypes.JSON` MRO entry
- `bind_expression` / `column_expression` apply `jsonb()` / `json()`
  transparently; existing `result_processor` from `sqltypes.JSON` handles
  deserialization without changes
- Added `sqlite_jsonb` requirement (checks for SQLite >= 3.45 and that
  `jsonb()` is available, since it is a loadable extension)

`test/dialect/sqlite/test_types.py::JSONBTest` (8 tests):
- DDL renders `JSONB`
- Reflection returns `sqlite.JSONB`
- Round-trip read/write including `None`
- Sub-object extraction via `[]` indexing
- Compiled SQL shows `jsonb(?)` on INSERT and `json(col)` on SELECT
- `typeof(col)` returns `blob` confirming binary storage

Closes: #13261
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13261
Pull-request-sha: 81b93af698e0222a9262614d39dd5ade6b640273

Change-Id: Ic38704674d30aa3d1bb5ce1e8ef5e4b0562ad91a

2 weeks agosupport mypy 2.0
Mike Bayer [Thu, 7 May 2026 15:54:58 +0000 (11:54 -0400)] 
support mypy 2.0

mypy just went to 2.0.

and there seems to be...

exactly one "type: ignore" to remove and...that's it?

well OK!

Change-Id: I29f919641acc0e970b566c850063db7ecad70ed9

2 weeks agoMerge "Fixes: #10673: make declared_attr covariant" into main
Michael Bayer [Thu, 7 May 2026 15:32:20 +0000 (15:32 +0000)] 
Merge "Fixes: #10673: make declared_attr covariant" into main

2 weeks agoReplace logging.WARN by logging.WARNING (#13277)
Léo Gallot [Tue, 5 May 2026 19:01:21 +0000 (21:01 +0200)] 
Replace logging.WARN by logging.WARNING (#13277)

2 weeks agolimit pypy to one build, fix typo (#13275)
Matti Picus [Mon, 4 May 2026 12:51:32 +0000 (15:51 +0300)] 
limit pypy to one build, fix typo (#13275)

2 weeks agorestore skip of 3.14t with cext and greenlet
Federico Caselli [Sun, 3 May 2026 19:27:32 +0000 (21:27 +0200)] 
restore skip of 3.14t with cext and greenlet

Change-Id: Ia75ab15c73f5a93f5eb2b6b99870aab824d0a43d

2 weeks agoBump pypa/cibuildwheel from 3.3.0 to 3.4.1 (#13271)
dependabot[bot] [Sat, 2 May 2026 18:33:39 +0000 (20:33 +0200)] 
Bump pypa/cibuildwheel from 3.3.0 to 3.4.1 (#13271)

* Bump pypa/cibuildwheel from 3.3.0 to 3.4.1

Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.3.0 to 3.4.1.
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v3.3.0...v3.4.1)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 3.4.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
* remove wheels for 3.13t since it's deprecated

Change-Id: I51157a09e7b01d5b23adc10d9a4b386776dedf7e

* remove tests from 3.13t

Change-Id: I73bb2761d07b0c8f549a4ba8ee7299dec6907df7

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Federico Caselli <cfederico87@gmail.com>
3 weeks agoBump actions/checkout from 4 to 6 (#13273)
dependabot[bot] [Thu, 30 Apr 2026 19:57:42 +0000 (21:57 +0200)] 
Bump actions/checkout from 4 to 6 (#13273)

Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
3 weeks agoBump docker/setup-qemu-action from 3 to 4 (#13272)
dependabot[bot] [Thu, 30 Apr 2026 19:54:35 +0000 (21:54 +0200)] 
Bump docker/setup-qemu-action from 3 to 4 (#13272)

Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
3 weeks agoBump actions/setup-python from 5 to 6 (#13270)
dependabot[bot] [Thu, 30 Apr 2026 19:53:11 +0000 (21:53 +0200)] 
Bump actions/setup-python from 5 to 6 (#13270)

Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
3 weeks agodocs: fix typo pool_echo -> echo_pool (#13269)
Léo Gallot [Thu, 30 Apr 2026 19:51:19 +0000 (21:51 +0200)] 
docs: fix typo pool_echo -> echo_pool (#13269)

3 weeks agoFixes: #10673: make declared_attr covariant
Luiz Felipe Neves [Thu, 30 Apr 2026 17:06:25 +0000 (13:06 -0400)] 
Fixes: #10673: make declared_attr covariant
<!-- Provide a general summary of your proposed changes in the Title field above -->

### Description
<!-- Describe your changes in detail -->
I made declared_attr covariant as suggested in #10673. mypy didn't seem to complain. Added a regression test for the use case that was asked for. Unfortunately, it seems like using `Mapped[int | UUID]` directly in the Protocol won't work:

```python
class CompareProtocol(Protocol):
    id: Mapped[int | UUID]
```

Because mypy will see this as a settable variable and not as a SQLAlchemy descriptor. Using `@property` instead seems to work and it's what I used in the test (perhaps it should be documented as the way to achieve this?):

```python
class CompareProtocol(Protocol):
    @property
    def id(self) -> Mapped[int | UUID]: ...
```

### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)

-->

This pull request is:

- [ ] A documentation / typographical / small typing error fix
- Good to go, no issue or tests are needed
- [X] A short code fix
- please include the issue number, and create an issue if none exists, which
  must include a complete example of the issue.  one line code fixes without an
  issue and demonstration will not be accepted.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.   one line code fixes without tests will not be accepted.
- [ ] A new feature implementation
- please include the issue number, and create an issue if none exists, which must
  include a complete example of how the feature would look.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.

Closes: #13266
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13266
Pull-request-sha: 8edd2841f4bbe61f8bb9bc15a7a57e0560698779

Change-Id: I7d63ad43df0ab34ee7c7389a007191be91efa574

3 weeks agoPostgresql default to no backslash escaping
Federico Caselli [Wed, 29 Apr 2026 20:11:35 +0000 (22:11 +0200)] 
Postgresql default to no backslash escaping

Changed the default backslash escape value in the PostgreSQL dialect to
``False`` to align it with the default value of
``standard_conforming_strings=on``. This change should not affect most users
since the value is set at driver initialization on first connect.

Fixes: #13268
Change-Id: I9b7986f1ee466fab3cab88e3f6117e313e3376cd

3 weeks agodocs: fix incorrect execution context class reference (#13254)
Léo Gallot [Wed, 29 Apr 2026 19:56:29 +0000 (21:56 +0200)] 
docs: fix incorrect execution context class reference (#13254)

4 weeks agoMerge "Remove unused TypeVars and compat import from typing modules" into main
Michael Bayer [Fri, 24 Apr 2026 21:38:50 +0000 (21:38 +0000)] 
Merge "Remove unused TypeVars and compat import from typing modules" into main

4 weeks agoconfigurable chunksize parameter for selectinload
bekapono [Wed, 22 Apr 2026 21:15:29 +0000 (17:15 -0400)] 
configurable chunksize parameter for selectinload

Added :paramref:`.selectinload.chunksize` parameter to :func`.selectinload`
allowing users to configure the number of primary keys sent per IN clause
when loading reltaionships. Pull request courtesy bekapono.

Fixes: #11450
Closes: #13235
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13235
Pull-request-sha: 360585a48c0fe898aa249769e9c7c1171f9e0988

Change-Id: Id09776b7ba53c630a780f128fc67dfdc085a4062

4 weeks agoRemove unused TypeVars and compat import from typing modules
Shamil Abdulaev [Thu, 23 Apr 2026 17:09:07 +0000 (13:09 -0400)] 
Remove unused TypeVars and compat import from typing modules

## Summary

Removes 4 dead symbols from SQLAlchemy's typing modules. Each symbol has **zero references** across `lib/`, `test/`, `doc/`, `tools/`, and `examples/` — verified by grep for direct references, string forward references, and `getattr`-style dynamic access.

## Changes

**`lib/sqlalchemy/util/typing.py`**
- Remove `from . import compat` — unused module import; the only occurrence of `compat` in the file is in a code comment on line 221
- Remove `_KT_co = TypeVar("_KT_co", covariant=True)` — unused TypeVar
- Remove `_KT_contra = TypeVar("_KT_contra", contravariant=True)` — unused TypeVar

**`lib/sqlalchemy/orm/_typing.py`**
- Remove `_T_co = TypeVar("_T_co", bound=Any, covariant=True)` — orphaned; `orm.base` imports `_T_co` from `sql._typing` instead, and other orm modules (`interfaces.py`, `attributes.py`) define their own local `_T_co`

Total: **-7 lines**, no additions.

## Verification

For each removed symbol:

| Symbol | Repo-wide grep result |
|---|---|
| `compat` (in `util/typing.py`) | 0 references to `compat.` or `util.typing.compat` outside the import itself |
| `_KT_co` | 1 hit total (the removed definition line) |
| `_KT_contra` | 1 hit total (the removed definition line) |
| `_T_co` (in `orm/_typing.py`) | No `from sqlalchemy.orm._typing import _T_co` or `from ..orm._typing import _T_co` anywhere; all consumers import from `sql._typing` or define locally |

Additionally checked:
- No `__all__` references
- No string forward references (e.g. `"_KT_co"`)
- No `getattr(..., "_T_co")` or similar dynamic access
- No re-exports via `util/__init__.py` or any other module
- `test/base/test_typing_utils.py` (which imports `util.typing as sa_typing`) does not touch any of these names

## Test plan

- [x] `pre-commit` hooks pass (black, zimports, flake8)
- [x] `import sqlalchemy`, `sqlalchemy.orm`, `sqlalchemy.util.typing`, `sqlalchemy.orm._typing`, `sqlalchemy.sql._typing`, `sqlalchemy.dialects._typing` — all import cleanly
- [x] Broad import smoke test: `Mapped`, `DeclarativeBase`, `relationship`, `Session`, `Mapper`, `mapped_column`, `Column`, `select`, `create_engine`, `MetaData`, `QueuePool`, `hybrid_property`, `association_proxy` — all import cleanly
- [x] Full `tox` / test suite — would appreciate CI confirmation

## Not included (intentionally)

- `LiteralString` re-export in `util/typing.py:54` — has 0 in-tree consumers but is an explicit `as X as X` public re-export; kept for API stability
- `is_origin_of` rename to `_is_origin_of` — used only internally by `is_union`, but renaming is a minor breaking change not worth the churn

Closes: #13244
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13244
Pull-request-sha: 8242f373685c35264ffd52071345a6dfce855277

Change-Id: Iae389447ac46599df27ab9776ff5ad19dfef4e2c

4 weeks agoMerge "Accept OrderByLists in order_by" into main
Michael Bayer [Wed, 22 Apr 2026 13:01:26 +0000 (13:01 +0000)] 
Merge "Accept OrderByLists in order_by" into main

4 weeks agoUse python to invoke pip
Federico Caselli [Tue, 21 Apr 2026 20:26:06 +0000 (22:26 +0200)] 
Use python to invoke pip

Fixes #13246 (hopefully)

Change-Id: If57a59e92ec933a1611c64534669a602ff2f3a92

4 weeks agoMerge "narrow scope of _correct_for_mysql_bugs_88718_96365" into main
Michael Bayer [Tue, 21 Apr 2026 17:17:36 +0000 (17:17 +0000)] 
Merge "narrow scope of _correct_for_mysql_bugs_88718_96365" into main

4 weeks agoAccept OrderByLists in order_by
Tobias Petersen [Tue, 21 Apr 2026 16:48:17 +0000 (12:48 -0400)] 
Accept OrderByLists in order_by

Add OrderByRole to acceptable arguments for order_by

Fixes: #13248
### Description
Add OrderByRole to acceptable arguments for order_by to solve typing regression

### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)

-->

This pull request is:

- [x] A documentation / typographical / small typing error fix
- Good to go, no issue or tests are needed
- [x] A short code fix
- please include the issue number, and create an issue if none exists, which
  must include a complete example of the issue.  one line code fixes without an
  issue and demonstration will not be accepted.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.   one line code fixes without tests will not be accepted.
- [ ] A new feature implementation
- please include the issue number, and create an issue if none exists, which must
  include a complete example of how the feature would look.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.

**Have a nice day!**

Closes: #13251
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13251
Pull-request-sha: 267e33f31139d4b6c6c3309b5875e1896e10e743

Change-Id: I0778cdecfebfb12bafc5b6027763ae5f5dcf02a2

4 weeks agonarrow scope of _correct_for_mysql_bugs_88718_96365
Mike Bayer [Mon, 20 Apr 2026 13:30:35 +0000 (09:30 -0400)] 
narrow scope of _correct_for_mysql_bugs_88718_96365

Narrowed the scope of the internal workaround for MySQL bugs `#88718
<https://bugs.mysql.com/bug.php?id=88718>`_ and `#96365
<https://bugs.mysql.com/bug.php?id=96365>`_ so that it is only applied
where needed: MySQL 8.0.1 through 8.0.13 (where bug 88718 is present), and
on systems with ``lower_case_table_names=2`` (where bug 96365 applies,
typically macOS).  Previously the workaround was applied unconditionally
for all MySQL 8.0+ versions, which caused a ``KeyError`` during foreign key
reflection when the database user lacked SELECT privileges on referred
tables.

Fixes: #13243
Change-Id: I7c29f67d1653c5cd32f29e098f038fea1d56117b

4 weeks agodocs: fix typo 'nad' -> 'and' in DefaultDialect.construct_arguments docstring (#13245)
Bojun Chai [Mon, 20 Apr 2026 20:30:20 +0000 (04:30 +0800)] 
docs: fix typo 'nad' -> 'and' in DefaultDialect.construct_arguments docstring (#13245)

Co-authored-by: Bojun Chai <bojunchai@microsoft.com>
5 weeks agohandle asyncpg InternalClientError
Mike Bayer [Fri, 17 Apr 2026 20:13:53 +0000 (16:13 -0400)] 
handle asyncpg InternalClientError

Fixed issue where the asyncpg driver could throw an insufficiently-handled
exception ``InternalClientError`` under some circumstances, leading to
connections not being properly marked as invalidated.

Fixes: #13241
References: https://github.com/MagicStack/asyncpg/issues/1069
Change-Id: Iaaf551b3d7b062cce62e13b441161583a484615f

5 weeks agoVersion 2.1.0b3 placeholder
Mike Bayer [Thu, 16 Apr 2026 20:16:54 +0000 (16:16 -0400)] 
Version 2.1.0b3 placeholder

5 weeks ago- 2.1.0b2 rel_2_1_0b2
Mike Bayer [Thu, 16 Apr 2026 20:04:09 +0000 (16:04 -0400)] 
- 2.1.0b2

5 weeks agodoc edits
Mike Bayer [Thu, 16 Apr 2026 20:02:37 +0000 (16:02 -0400)] 
doc edits

Change-Id: I2a30ceba5d27eba858396ab98ccb25e62d3dc3dc

5 weeks agoMerge "Add mypy ignore comments for Python 3.14 module imports" into main
Federico Caselli [Thu, 16 Apr 2026 19:45:42 +0000 (19:45 +0000)] 
Merge "Add mypy ignore comments for Python 3.14 module imports" into main

5 weeks agoadd missing versionadded annotation
Federico Caselli [Thu, 16 Apr 2026 19:06:55 +0000 (21:06 +0200)] 
add missing versionadded annotation

Change-Id: Id3ae0bcd9fef956bec0aa9c19ffc375472840774
References: #13238

5 weeks agoFix 'compatiblity' typo in sqlite dialect docstring (#13237)
Mukunda Rao Katta [Thu, 16 Apr 2026 18:56:30 +0000 (11:56 -0700)] 
Fix 'compatiblity' typo in sqlite dialect docstring (#13237)

Co-authored-by: MukundaKatta <mukundakatta@users.noreply.github.com>
5 weeks agoAdd mypy ignore comments for Python 3.14 module imports
Shamil Abdulaev [Thu, 16 Apr 2026 18:56:23 +0000 (14:56 -0400)] 
Add mypy ignore comments for Python 3.14 module imports

Fixes #13240

Use `sys.version_info >= (3, 14)` instead of the `py314` variable for
the py314-only imports block (`annotationlib`, `string.templatelib`).

mypy has built-in support for `sys.version_info` guards and only
type-checks the reachable branch, while a plain variable like `py314`
causes mypy to check both branches — leading to `import-not-found` on
<3.14 and `unused-ignore` on 3.14 if `type: ignore` comments are added.

Closes: #13239
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13239
Pull-request-sha: f58bfc11694c71020b98ed69d8400a0173be096b

Change-Id: Ib5e2361e849a3f14f90d0da34800c1d31f8bf201

5 weeks agoMerge "Improve pg two-phase transactions" into main
Michael Bayer [Wed, 15 Apr 2026 18:20:23 +0000 (18:20 +0000)] 
Merge "Improve pg two-phase transactions" into main

5 weeks agoImprove pg two-phase transactions
Federico Caselli [Mon, 13 Apr 2026 21:53:00 +0000 (23:53 +0200)] 
Improve pg two-phase transactions

Improve handling of two phase transaction identifiers for PostgreSQL
when the identifier is provided by the user.
As part of this change the psycopg dialect was updated to use the DBAPI
two phase transaction API instead of executing the SQL directly.

Fixes: #13229
Change-Id: If8301a7253b4a0c88e5323c9a052c3a9fa258780

5 weeks agoImprove escaping in pysqlcipher
Federico Caselli [Mon, 13 Apr 2026 20:26:48 +0000 (22:26 +0200)] 
Improve escaping in pysqlcipher

Escape key and pragma values when utilizing the pysqlcipher dialect.

Fixes: #13230
Change-Id: I7583577a3e00e2f2986e50f32136a9ef005eb28a

7 weeks agoMerge "Add JSON type support for Oracle dialect" into main
Michael Bayer [Fri, 3 Apr 2026 19:19:48 +0000 (19:19 +0000)] 
Merge "Add JSON type support for Oracle dialect" into main

7 weeks agoAdd JSON type support for Oracle dialect
abdallah elhdad [Tue, 17 Mar 2026 14:33:29 +0000 (10:33 -0400)] 
Add JSON type support for Oracle dialect

Added support for the :class:`_sqltypes.JSON` datatype when using the
Oracle database with the oracledb dialect.  JSON values are serialized and
deserialized using configurable strategies that accommodate Oracle's native
JSON type available as of Oracle 21c.  Pull request courtesy Abdallah
Alhadad.

This fix also includes new dialect-level indicators for JSON support;
some attention given to issue #13213 indicates we can close that issue.

Fixes: #10375
Closes: #13065
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13065
Pull-request-sha: 9a89237f4ff7f4d7fa55de60ee9e616b8e15bbf5

Change-Id: I8cbe35bc632dc9419642ddca8bf4ba9c20c0ae37

7 weeks agocherry-pick changelog update for 2.0.50
Mike Bayer [Fri, 3 Apr 2026 16:38:35 +0000 (12:38 -0400)] 
cherry-pick changelog update for 2.0.50

7 weeks agocherry-pick changelog from 2.0.49
Mike Bayer [Fri, 3 Apr 2026 16:38:35 +0000 (12:38 -0400)] 
cherry-pick changelog from 2.0.49

7 weeks agoupdate for mypy 1.20.0
Mike Bayer [Wed, 1 Apr 2026 18:31:21 +0000 (14:31 -0400)] 
update for mypy 1.20.0

Change-Id: I95f72b8a1818b79d01d26531202199f24fe3b808

7 weeks agoreally remove cx_oracle from test setup
Mike Bayer [Wed, 1 Apr 2026 19:45:53 +0000 (15:45 -0400)] 
really remove cx_oracle from test setup

in 6282bcef11781b5ded26d48b22b5f we tried to disable cx_oracle
testing bug failed because pyproject was still pulling it in.
really fix this time

Change-Id: If5a46bf1ad9a9ee48e8693cccdc4b8b40cee392d

7 weeks agoMerge "accommodate subclass mapper in post-loader entity_isa check" into main
Michael Bayer [Tue, 31 Mar 2026 16:24:58 +0000 (16:24 +0000)] 
Merge "accommodate subclass mapper in post-loader entity_isa check" into main

7 weeks agoCoercion warning feedback for unary distinct outside aggregate function
bekapono [Tue, 24 Mar 2026 01:30:46 +0000 (21:30 -0400)] 
Coercion warning feedback for unary distinct outside aggregate function

A warning is emitted when using the standalone :func:`_.sql.distinct`
function in a :func:`_sql.select` columns list outside of an aggregate
function; this function is not intended as a replacement for the use of
:meth:`.Select.distinct`. Pull request courtesy bekapono.

Fixes: #11526
Closes: #13162
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13162
Pull-request-sha: c6e8be7a49fecb1402dc249c84e7f982c1c34821

Change-Id: Ibbdd64a922c62a7a9ead566590ad854db4066565

7 weeks agoaccommodate subclass mapper in post-loader entity_isa check
Mike Bayer [Sun, 29 Mar 2026 17:46:39 +0000 (13:46 -0400)] 
accommodate subclass mapper in post-loader entity_isa check

Fixed issue where using chained loader options such as
:func:`_orm.selectinload` after :func:`_orm.joinedload` with
:meth:`_orm.PropComparator.of_type` for a polymorphic relationship would
not properly apply the chained loader option. The loader option is now
correctly applied when using a call such as
``joinedload(A.b.of_type(poly)).selectinload(poly.SubClass.c)`` to eagerly
load related objects.

Fixes: #13209
Change-Id: I2d14838f1b1a9a2b18dc52137910dab0bccf0dd5

7 weeks agoMerge "fix: Session.get() with with_for_update=False skips identity map" into main
Michael Bayer [Sun, 29 Mar 2026 17:10:10 +0000 (17:10 +0000)] 
Merge "fix: Session.get() with with_for_update=False skips identity map" into main

8 weeks agoapply _path_with_polymorphic in prepend as well
Mike Bayer [Fri, 27 Mar 2026 18:24:10 +0000 (14:24 -0400)] 
apply _path_with_polymorphic in prepend as well

Fixed issue where using :meth:`_orm.Load.options` to apply a chained loader
option such as :func:`_orm.joinedload` or :func:`_orm.selectinload` with
:meth:`_orm.PropComparator.of_type` for a polymorphic relationship would
not generate the necessary clauses for the polymorphic subclasses. The
polymorphic loading strategy is now correctly propagated when using a call
such as ``joinedload(A.b).options(joinedload(B.c.of_type(poly)))`` to match
the behavior of direct chaining e.g.
``joinedload(A.b).joinedload(B.c.of_type(poly))``.

Fixes: #13202
Change-Id: I7b2ce2dd10a7f8583ff99495b0a65fa1a895ee29

8 weeks agofix: Session.get() with with_for_update=False skips identity map
joshuaswanson [Fri, 27 Mar 2026 16:41:11 +0000 (12:41 -0400)] 
fix: Session.get() with with_for_update=False skips identity map

Fixes #13176.

`Session.get()` checks `with_for_update is None` to decide whether to look up the identity map. Passing `with_for_update=False` fails this check and always hits the database, even though `ForUpdateArg._from_argument` already treats `False` and `None` identically (both return `None`). Changed to `with_for_update in (None, False)` to match.

Closes: #13199
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13199
Pull-request-sha: c639b8723888947317598df387c5e3e4d87acac4

Change-Id: I0584873f46099afadcdd760c0a267ae4d30528eb

8 weeks agouse getattr for metadata, registry and type_annotation_map
Federico Caselli [Tue, 24 Mar 2026 20:08:03 +0000 (21:08 +0100)] 
use getattr for metadata, registry and type_annotation_map

The ``metadata``, ``type_annotation_map``, or ``registry`` can now be
set up in a declarative base also via a mixin class, not only by
directly setting them on the subclass like before.
The declarative class setup now uses ``getattr()`` to look for these
attributes, instead of relying only on the class ``__dict__``.

Fixes: #13198
Change-Id: I032f0064aefb36e5c5a2f1186d7edd30d2863047

8 weeks agoMerge "detect and accommodate reverse condition for loader strategy" into main
Michael Bayer [Mon, 23 Mar 2026 21:21:49 +0000 (21:21 +0000)] 
Merge "detect and accommodate reverse condition for loader strategy" into main

8 weeks agolink insert.value to data insert tutorial
Federico Caselli [Mon, 23 Mar 2026 20:59:23 +0000 (21:59 +0100)] 
link insert.value to data insert tutorial

Change-Id: I892fd7357f88c0e8d16e8e6fb74f18f4541ff795

8 weeks agodetect and accommodate reverse condition for loader strategy
Mike Bayer [Mon, 23 Mar 2026 18:13:02 +0000 (14:13 -0400)] 
detect and accommodate reverse condition for loader strategy

Fixed issue where chained :func:`_orm.joinedload` options would not be
applied correctly when the final relationship in the chain is declared on a
base mapper and accessed through a subclass mapper in a
:func:`_orm.with_polymorphic` query. The path registry now correctly
computes the natural path when a property declared on a base class is
accessed through a path containing a subclass mapper, ensuring the loader
option can be located during query compilation.

Fixes: #13193
Change-Id: I9ec83a0f184caed2bf6dd087b20c3538d6c23597

8 weeks agoMerge "Add frame exclusion support for window functions" into main
Michael Bayer [Mon, 23 Mar 2026 12:29:36 +0000 (12:29 +0000)] 
Merge "Add frame exclusion support for window functions" into main

2 months agoMerge "mssql: fall back to base type for alias types during reflection" into main
Michael Bayer [Fri, 20 Mar 2026 20:37:40 +0000 (20:37 +0000)] 
Merge "mssql: fall back to base type for alias types during reflection" into main

2 months agomssql: fall back to base type for alias types during reflection
Carlos Serrano [Wed, 18 Mar 2026 15:37:08 +0000 (11:37 -0400)] 
mssql: fall back to base type for alias types during reflection

Fixed regression from version 2.0.42 caused by :ticket:`12654` where the
updated column reflection query would receive SQL Server "type alias" names
for special types such as ``sysname``, whereas previously the base name
would be received (e.g. ``nvarchar`` for ``sysname``), leading to warnings
that such types could not be reflected and resulting in :class:`.NullType`,
rather than the expected :class:`.NVARCHAR` for a type like ``sysname``.
The column reflection query now joins ``sys.types`` a second time to look
up the base type when the user type name is not present in
:attr:`.MSDialect.ischema_names`, and both names are checked in
:attr:`.MSDialect.ischema_names` for a match. Pull request courtesy Carlos
Serrano.

Fixes: #13181
Fixes: #13182
Closes: #13178
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13178
Pull-request-sha: be5c3850594665c0154ae215d4f9c322cc5a3f5a

Change-Id: I7fe86b80dfa45b208f7d97003ee5b1df3f07bfe7

2 months agoMerge "Remove version warning in SQL Server" into main
Michael Bayer [Fri, 20 Mar 2026 19:24:52 +0000 (19:24 +0000)] 
Merge "Remove version warning in SQL Server" into main

2 months agoMerge "Allow escaped quotes in Postgres quoted identifier" into main
Michael Bayer [Fri, 20 Mar 2026 19:23:30 +0000 (19:23 +0000)] 
Merge "Allow escaped quotes in Postgres quoted identifier" into main

2 months agoremove cx_oracle from testing
Mike Bayer [Thu, 19 Mar 2026 00:21:20 +0000 (20:21 -0400)] 
remove cx_oracle from testing

cx_oracle is no longer able to build from its .tar.gz form
reliably because it does not include setuptools in its build
dependencies.   It still can be built if pip is given
--no-build-isolation, or if a wheel file is installed rather than
the .tar.gz, but given how quickly cx_oracle has been pushed
aside by oracledb it's not really that important to be testing
it anymore.

Change-Id: I8a4b2cffabe5275a0df88b5a624ecd6379d84d37

2 months agoMerge "Add typing overloads to Query.__getitem__ and AppenderQuery.__getitem__" into...
Federico Caselli [Wed, 18 Mar 2026 23:37:29 +0000 (23:37 +0000)] 
Merge "Add typing overloads to Query.__getitem__ and AppenderQuery.__getitem__" into main

2 months agoAllow escaped quotes in Postgres quoted identifier
Austin Graham [Wed, 18 Mar 2026 14:57:13 +0000 (10:57 -0400)] 
Allow escaped quotes in Postgres quoted identifier

<!-- Provide a general summary of your proposed changes in the Title field above -->

### Description
Issue: https://github.com/sqlalchemy/sqlalchemy/issues/10902

Hello! This is my first PR here, so please let me know what I may have missed in terms of having a valuable contribution. I was looking through issues to grab an easy first one, and found this. Looks like someone else was going to have a go at it, but never did.

I simply added a small change to the FK regex in for Postgres that allows anything not quotes alongside escaped double quotes. Test is included for the scenario mentioned in the issue. Alongside that, I didn't see a test for general quoted strings, so I added another one that includes spaces and dashes, in my experience common things to be used inside quoted identifiers.

A manual test as well:
DB setup:
```
austin_test_bug=# CREATE TABLE """test_parent_table-quoted""" (id SERIAL PRIMARY KEY, val INTEGER);
CREATE TABLE
austin_test_bug=# CREATE TABLE test_child_table_ref_quoted (id SERIAL, parent INTEGER, CONSTRAINT fk_parent FOREIGN KEY (parent) REFERENCES """test_parent_table-quoted"""(id));
CREATE TABLE
austin_test_bug=# \d+
                                                     List of relations
 Schema |                Name                |   Type   |  Owner   | Persistence | Access method |    Size    | Description
--------+------------------------------------+----------+----------+-------------+---------------+------------+-------------
 public | "test_parent_table-quoted"         | table    | postgres | permanent   | heap          | 0 bytes    |
 public | "test_parent_table-quoted"_id_seq  | sequence | postgres | permanent   |               | 8192 bytes |
 public | test_child_table_ref_quoted        | table    | postgres | permanent   | heap          | 0 bytes    |
 public | test_child_table_ref_quoted_id_seq | sequence | postgres | permanent   |               | 8192 bytes |
(4 rows)

```

And the python:
```
>>> from sqlalchemy import create_engine, inspect
>>> engine = create_engine('postgresql://scott:tiger@localhost:5432/austin_test_bug')
>>> connection = engine.connect()
>>> inspect(connection).get_multi_foreign_keys()
{(None, '"test_parent_table-quoted"'): [], (None, 'test_child_table_ref_quoted'): [{'name': 'fk_parent', 'constrained_columns': ['parent'], 'referred_schema': None, 'referred_table': '"test_parent_table-quoted"', 'referred_columns': ['id'], 'options': {}, 'comment': None}]}
```

### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)

-->

This pull request is:

- [ ] A documentation / typographical / small typing error fix
- Good to go, no issue or tests are needed
- [x] A short code fix
- please include the issue number, and create an issue if none exists, which
  must include a complete example of the issue.  one line code fixes without an
  issue and demonstration will not be accepted.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.   one line code fixes without tests will not be accepted.
- [ ] A new feature implementation
- please include the issue number, and create an issue if none exists, which must
  include a complete example of how the feature would look.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.

**Have a nice day!**

Fixes: #10902
Closes: #13179
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13179
Pull-request-sha: 8890dc3250a30fc62b8f15cd1da1353b81524c00

Change-Id: I185c2cb062740551ab931368de602054eb5a4acd

2 months agoci: add riscv64 wheel builds via QEMU (#13183)
Bruno Verachten [Wed, 18 Mar 2026 19:49:31 +0000 (20:49 +0100)] 
ci: add riscv64 wheel builds via QEMU (#13183)

Signed-off-by: Bruno Verachten <gounthar@gmail.com>
2 months agoRemove version warning in SQL Server
Federico Caselli [Wed, 18 Mar 2026 19:45:39 +0000 (20:45 +0100)] 
Remove version warning in SQL Server

Remove warning for SQL Server dialect when a new version is detected.
The warning was originally added more than 15 years ago due to an unexpected
value returned when using an old version of FreeTDS.
The assumption is that since then the issue has been resolved, so make the
SQL Server dialect behave like the other ones that don't have an upper bound
check on the version number.

This effectively reverts 64d92c836ce029e33b57bcabd4ca76944549e022
that was added for #1825

Fixes: #13185
Change-Id: I79c6951b2fbb6da2caefca97dc3e1b9d8f48f0ab

2 months agoclarify the Result.closed attribute
Mike Bayer [Wed, 18 Mar 2026 19:30:54 +0000 (15:30 -0400)] 
clarify the Result.closed attribute

document that Result.returns_rows is usually what people
want when they are looking for this.

References: #13184
Change-Id: Ia0b23e7482115bca3f93d20e21e53598aa9d084c

2 months agoMerge "ensure function classes are not shadowed" into main
Michael Bayer [Wed, 18 Mar 2026 15:01:24 +0000 (15:01 +0000)] 
Merge "ensure function classes are not shadowed" into main

2 months agoMerge "Improve typing story for core from clauses." into main
Federico Caselli [Tue, 17 Mar 2026 15:35:26 +0000 (15:35 +0000)] 
Merge "Improve typing story for core from clauses." into main

2 months agoAdd frame exclusion support for window functions
Varun Chawla [Tue, 24 Feb 2026 14:10:50 +0000 (09:10 -0500)] 
Add frame exclusion support for window functions

Add the `exclude` parameter to the `Over` construct and all `.over()`
methods, enabling SQL standard frame exclusion clauses
`EXCLUDE CURRENT ROW`, `EXCLUDE GROUP`, `EXCLUDE TIES`,
`EXCLUDE NO OTHERS` in window functions.
Pull request courtesy of Varun Chawla.

Fixes #11671
Closes: #13117
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13117
Pull-request-sha: 23f9d34dd80c45dff68ecc8c08331acf22b82279

Change-Id: I8efdb06876d5a11a9f5ed9abec2c187c6c9b7e5e

2 months agoMerge "Update _NamingSchemaCallable to support Index" into main
Federico Caselli [Mon, 16 Mar 2026 20:20:21 +0000 (20:20 +0000)] 
Merge "Update _NamingSchemaCallable to support Index" into main

2 months agoensure function classes are not shadowed
Federico Caselli [Thu, 12 Mar 2026 22:34:27 +0000 (23:34 +0100)] 
ensure function classes are not shadowed

Ensure the _FunctionGenerator method do not shadow the function class
of the same name

Fixed a typing issue where the typed members of :data:`.func` would return
the appropriate class of the same name, however this creates an issue for
typecheckers such as Zuban and pyrefly that assume :pep:`749` style
typechecking even if the file states that it's a :pep:`563` file; they see
the returned name as indicating the method object and not the class object.
These typecheckers are actually following along with an upcoming test
harness that insists on :pep:`749` style name resolution for this case
unconditionally.  Since :pep:`749` is the way of the future regardless,
differently-named type aliases have been added for these return types.

Fixes: #13167
Change-Id: If58a3858001c78ab21b2ed343205dfd9ce868576

2 months agoImprove typing story for core from clauses.
Federico Caselli [Thu, 22 Jan 2026 23:04:56 +0000 (00:04 +0100)] 
Improve typing story for core from clauses.

Most :class:`_sql.FromClause` subclasses are not generic on
:class:`.TypedColumns` subclasses, that can be used to type their
:attr:`_sql.FromClause.c` collection.
This applied to :class:`_schema.Table`, :class:`_sql.Join`,
:class:`_sql.Subquery`, :class:`_sql.CTE` and more.

Fixes: #13085
Change-Id: I724aca887a85c4a401df875903eda12125066680

2 months agoMerge "allow JSON, JSONB, etc. to be parameterized, type HSTORE" into main
Michael Bayer [Mon, 9 Mar 2026 22:57:59 +0000 (22:57 +0000)] 
Merge "allow JSON, JSONB, etc. to be parameterized, type HSTORE" into main

2 months agoUpdate _NamingSchemaCallable to support Index
Martin Baláž [Mon, 9 Mar 2026 17:19:04 +0000 (13:19 -0400)] 
Update _NamingSchemaCallable to support Index

<!-- Provide a general summary of your proposed changes in the Title field above -->

### Description
<!-- Describe your changes in detail -->
According to [the documentation](https://docs.sqlalchemy.org/en/21/core/metadata.html#sqlalchemy.schema.MetaData.params.naming_convention), the values associated with user-defined “token” keys in `naming_convention` should be callables of the form `fn(constraint, table)`, which accepts the constraint/index object and Table. However, the type alias `_NamingSchemaCallable` accepts only constraint in the first argument. I propose to update `_NamingSchemaCallable` to accept also an index.

### Example
```python
import sqlalchemy

def include_0_N_name(
schema_item: sqlalchemy.Index | sqlalchemy.Constraint,
table: sqlalchemy.Table,
) -> str:
tokens = []

for column in schema_item.dialect_options.get('postgresql', {}).get('include', []):
tokens.append("_")
tokens.append(column.name)

return "".join(tokens)

metadata = sqlalchemy.MetaData(
naming_convention={
"include_0_N_name": include_0_N_name,
"ix": "%(table_name)s_%(column_0_N_name)s%(include_0_N_name)s_idx",
"uq": "%(table_name)s_%(column_0_N_name)s%(include_0_N_name)s_key",
"fk": "%(table_name)s_%(column_0_N_name)s%(include_0_N_name)s_fkey",
"pk": "%(table_name)s_pkey",
},
)
```

### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)

-->

This pull request is:

- [x] A documentation / typographical / small typing error fix
- Good to go, no issue or tests are needed
- [ ] A short code fix
- please include the issue number, and create an issue if none exists, which
  must include a complete example of the issue.  one line code fixes without an
  issue and demonstration will not be accepted.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.   one line code fixes without tests will not be accepted.
- [ ] A new feature implementation
- please include the issue number, and create an issue if none exists, which must
  include a complete example of how the feature would look.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.

Closes: #13161
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13161
Pull-request-sha: cf53bd722932741bceaba1dd16a52ba93ff579cc

Change-Id: I0daf8a6eeb458aaa09f3392e00d98c27dbf8ca3c

2 months agodocs: fix RelationshipProperty comparator cross-references (#13155)
Dr Alex Mitre [Fri, 6 Mar 2026 21:57:04 +0000 (15:57 -0600)] 
docs: fix RelationshipProperty comparator cross-references (#13155)

2 months agoallow JSON, JSONB, etc. to be parameterized, type HSTORE
Mike Bayer [Wed, 18 Feb 2026 15:12:52 +0000 (10:12 -0500)] 
allow JSON, JSONB, etc. to be parameterized, type HSTORE

Improved typing of :class:`_sqltypes.JSON` as well as dialect specific
variants like :class:`_postgresql.JSON` to include generic capabilities, so
that the types may be parameterized to indicate any specific type of
contents expected, e.g. ``JSONB[list[str]]()``.

Also types HSTORE

Fixes: #13131
Change-Id: Ia089ba4e3cebf6339a5420b2923cd267c4e6891a

2 months agoMerge "mssql-python" into main
Michael Bayer [Fri, 6 Mar 2026 19:06:20 +0000 (19:06 +0000)] 
Merge "mssql-python" into main

2 months agomssql-python
Mike Bayer [Wed, 17 Sep 2025 19:31:11 +0000 (15:31 -0400)] 
mssql-python

Added support for the ``mssql-python`` driver, Microsoft's official Python
driver for SQL Server.

Fixes: #12869
Change-Id: I9ce0fef1dd1105c20833cc6a46f24ac9580c4b39

2 months agoensure DeclarativeBase attributes are documented
Federico Caselli [Thu, 5 Mar 2026 22:54:44 +0000 (23:54 +0100)] 
ensure DeclarativeBase attributes are documented

Change-Id: I89af45911906aa9979b7c34d106fea424236ebb4