]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
migration note on subqueries
authorjonathan vanasco <jonathan@2xlp.com>
Sat, 11 Jul 2026 17:16:58 +0000 (13:16 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 11 Jul 2026 19:04:52 +0000 (15:04 -0400)
Under 2.0, calls to `in_` and `not_in` no longer accept an explicit `.subquery()`.

Passing a `.subquery()` will cause typing issues from MyPy AND will raise runtime warnings.

There was no note of this in the migration guide.  This may be an effect of another change that is disclosed in the migration guide.  If so, I suggest nesting this text (or improved text describing this) under that section for ease in discovery and migration.

Added a note to the 2.0 migration guide.

<!-- 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: #11107
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/11107
Pull-request-sha: f8669da225bc7687208d2389c6ae3bf3c63f6aaf

Change-Id: Id33779cb126a700d9adebe5f08f9d6c085589db4
(cherry picked from commit c302b2ca46754ea49c5b24fdd8b6375aafb1df96)

doc/build/Makefile
doc/build/changelog/migration_20.rst

index 325da5046e665f148c6818f308fcea9111433e22..718887dd60919f0cc792404685014ac7794c76dd 100644 (file)
@@ -14,7 +14,7 @@ PAPEROPT_letter = -D latex_paper_size=letter
 ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
 # the i18n builder cannot share the environment and doctrees with the others
 I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-AUTOBUILDSPHINXOPTS = -T .
+AUTOBUILDSPHINXOPTS = -T -j auto .
 
 .PHONY: help clean html autobuild dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest dist-html site-mako gettext
 
index 7969c86c7bf4b9ec65155a6b4898bfafbe671536..fb5070a5609a48d48b5b5484327922f1cf049697 100644 (file)
@@ -549,6 +549,7 @@ The guide at :ref:`whatsnew_20_toplevel` provides an overview of
 new features and behaviors for SQLAlchemy 2.0 which extend beyond the base
 set of 1.4->2.0 API changes.
 
+
 2.0 Migration - Core Connection / Transaction
 ---------------------------------------------
 
@@ -2092,6 +2093,38 @@ when using an explicit :func:`_orm.aliased` object, both from a user point
 of view as well as how the internals of the SQLAlchemy ORM must handle it.
 
 
+Filtering with ``in_()``/``not_in()`` no longer accepts explicit subqueries
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Synopsis**
+
+Support for accepting explicit subqueries in specific filtering operations, such
+as :meth:`_sql.ColumnOperators.in_` and
+:meth:`_sql.ColumnOperators.not_in`, has been removed in 2.0. The following
+legacy usage will raise warnings and is incompatible with the type checking
+system::
+
+    subq = (session.query(User.id).filter(User.name == "foo")).subquery()
+    q = session.query(User).filter(User.id.in_(subq))
+
+**Migration to 2.0**
+
+Under 2.0, SQLAlchemy will automatically interpret a fully constructed query
+passed to :meth:`_sql.ColumnOperators.in_` and
+:meth:`_sql.ColumnOperators.not_in` as a subquery based on the
+implied context::
+
+    subq = select(User.id).filter(User.name == "foo")
+    stmt = session.execute(select(User).filter(User.id.in_(subq)))
+
+**Partial Migration Notes**
+
+A partial migration to 2.0 in which :class:`.orm.query.Query` is still utilized,
+must be updated for compliance with the new API as well::
+
+    subq = session.query(User.id).filter(User.name == "foo")
+    q = session.query(User).filter(User.id.in_(subq))
+
 .. _joinedload_not_uniqued:
 
 ORM Rows not uniquified by default