Commit Graph

17856 Commits

Author SHA1 Message Date
G Allajmi 9fe3c3cd30 Factor out constraints into separate methods
Fixed issue where PostgreSQL dialect options such as ``postgresql_include``
on :class:`.PrimaryKeyConstraint` and :class:`.UniqueConstraint` were
rendered in the wrong position when combined with constraint deferrability
options like ``deferrable=True``. Pull request courtesy G Allajmi.

Fixes: #12867
Closes: #13003
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13003
Pull-request-sha: 1a9216062f

Change-Id: I8c55d8faae25d56ff63c9126d569c01d8ee6c7dd
2025-12-09 15:12:34 -05:00
Mike Bayer 6785a09670 use os.urandom() for CTE, aliased anon id
Fixed issue where anonymous label generation for :class:`.CTE` constructs
could produce name collisions when Python's garbage collector reused memory
addresses during complex query compilation. The anonymous name generation
for :class:`.CTE` and other aliased constructs like :class:`.Alias`,
:class:`.Subquery` and others now use :func:`os.urandom` to generate unique
identifiers instead of relying on object ``id()``, ensuring uniqueness even
in cases of aggressive garbage collection and memory reuse.

Fixes: #12990
Change-Id: If56a53840684bc7d2b7637f1e154dfed1cac5f32
2025-12-09 15:23:29 +00:00
Federico Caselli f58ea194d5 update cibuildwheel to ensure python 3.14 is supported
Change-Id: Ic520ae7084dcc0660da0d70a0c33de251395ec50
2025-12-08 21:12:16 +01:00
Mike Bayer c7bd25650a fix typo
Change-Id: I5a440f9d3a8bb5afb45b0af4d9f1a112255d5f96
2025-12-08 11:40:34 -05:00
Michael Bayer f9f07ce096 Merge "support monotonic functions as sentinels" into main 2025-12-07 14:16:09 +00:00
Mike Bayer 437745e92e support monotonic functions as sentinels
Added support for monotonic server-side functions such as PostgreSQL 18's
``uuidv7()`` to work with the :ref:`engine_insertmanyvalues` feature.
By passing ``monotonic=True`` to any :class:`.Function`, the function can
be used as a sentinel for tracking row order in batched INSERT operations
with RETURNING, allowing the ORM and Core to efficiently batch INSERT
statements while maintaining deterministic row ordering.

Fixes: #13014
Change-Id: I2fabf96c8fbdb6c1d255fd4781cbd31fed17e1e9
2025-12-07 08:51:13 -05:00
Michael Bayer a1f066b06d Merge "Revert "behave more like dataclasses when creating them"" into main 2025-12-06 15:36:48 +00:00
Michael Bayer 4ff1d604f9 Revert "behave more like dataclasses when creating them"
This reverts commit be4e3e675e.

Reason for revert: everything has passed very well on jenkins, however GH actions is showing the two new test_cpython_142214 tests from 133f14dabe suddenly failing across hundreds of scenarios.  given the risk of this change since dataclasses are very weird, need to see what this is about.   im suspecting point release changes in older pythons like 3.10, 3.11, etc. which seems a bit ominous.

Change-Id: I7c98085b5e3482cad3291194e2ab1f8018db2eff
2025-12-06 15:07:25 +00:00
Michael Bayer 30d80ec1d4 Merge "behave more like dataclasses when creating them" into main 2025-12-06 14:09:35 +00:00
Mike Bayer 66d55b5199 fix / modernize short_selects example
Fixed the "short_selects" performance example where the cache was being
used in all the examples, making it impossible to compare performance with
and without the cache.   Less important comparisons like "lambdas" and
"baked queries" have been removed.

Change-Id: Ia55391ba23e01d2ed136c84f9c34bb16689ce10e
2025-12-05 17:44:57 -05:00
Federico Caselli be4e3e675e behave more like dataclasses when creating them
A change in the mechanics of how Python dataclasses are applied to classes
that use :class:`.MappedAsDataclass` or
:meth:`.registry.mapped_as_dataclass`, to no longer modify the
`__annotations__` collection that's on the class, instead manipulating
regular class-bound attributes in order to satisfy the class requirements
for the dataclass creation function.  This works around an issue that has
appeared in Python 3.14.1, provides for a much simpler implementation, and
also maintains accurate typing information about the attributes as the
dataclass is built.

Fixes: #13021
Change-Id: I6ae13db7f647ad04e202667d69f2b1bb385c032d
2025-12-05 14:13:09 -05:00
Mike Bayer 9a0d004331 filter_by works across multiple entities
The :meth:`_sql.Select.filter_by`, :meth:`_sql.Update.filter_by` and
:meth:`_sql.Delete.filter_by` methods now search across all entities
present in the statement, rather than limiting their search to only the
last joined entity or the first FROM entity. This allows these methods
to locate attributes unambiguously across multiple joined tables,
resolving issues where changing the order of operations such as
:meth:`_sql.Select.with_only_columns` would cause the method to fail.

If an attribute name exists in more than one FROM clause entity, an
:class:`_exc.AmbiguousColumnError` is now raised, indicating that
:meth:`_sql.Select.filter` (or :meth:`_sql.Select.where`) should be used
instead with explicit table-qualified column references.

Fixes: #8601
Change-Id: I6a46b8f4784801f95f7980ca8ef92f1947653572
2025-12-04 13:53:27 +00:00
Mike Bayer 133f14dabe Add a test for #13021
Confirmed the upstream fix for [1] given at [2] solves the issue
illustrated here, this patch adds a test for this case as our
existing tests did not catch this error in python 3.14.1.

Fixes: #13021
Change-Id: Ie6827279ccf2b2cb2e0fe6029aafdcfefc790f1f
2025-12-03 14:48:08 -05:00
Michael Bayer 229a71fb0a Merge "send same sub_stmt to after_cursor_execute as before" into main 2025-12-03 19:17:16 +00:00
Michael Bayer 3d64f83e6c Merge "run sentinel server side fns outside of VALUES" into main 2025-12-03 16:56:08 +00:00
Michael Bayer fa6f22beaf Merge "block json tests for non-json backends" into main 2025-12-03 13:13:17 +00:00
Federico Caselli 7dc465d94e Merge "[typing] Fix type error when passing Mapped columns to values()" into main 2025-12-03 07:41:20 +00:00
Mike Bayer a9e82a6abe block json tests for non-json backends
these were failing on Oracle which has no json type

Change-Id: I3c35c4f38c581378c74ee9dc3fb7a71655c5ee9c
2025-12-02 23:18:58 -05:00
Mike Bayer 6924f6c5d9 send same sub_stmt to after_cursor_execute as before
Fixed issue in the :meth:`.ConnectionEvents.after_cursor_execute` method
where the SQL statement and parameter list for an "insertmanyvalues"
operation sent to the event would not be the actual SQL / parameters just
emitted on the cursor, instead being the non-batched form of the statement
that's used as a template to generate the batched statements.

Fixes: #13018
Change-Id: Ib5b6c576f2c7a9ed275de30290d619cc651b4816
2025-12-02 23:10:10 -05:00
Mike Bayer c5d09f5ed4 run sentinel server side fns outside of VALUES
Fixed the structure of the SQL string used for the
:ref:`engine_insertmanyvalues` feature when an explicit sequence with
``nextval()`` is used. The SQL function invocation for the sequence has
been moved from being rendered inline within each tuple inside of VALUES to
being rendered once in the SELECT that reads from VALUES. This change
ensures the function is invoked in the correct order as rows are processed,
rather than assuming PostgreSQL will execute inline function calls within
VALUES in a particular order. While current PostgreSQL versions appear to
handle the previous approach correctly, the database does not guarantee
this behavior for future versions.

Fixes: #13015
Change-Id: Ia0a2a4e8f89e21852d7cb550dfa5d9ea9447b590
2025-12-02 22:52:57 -05:00
Yossi 40c2400af7 [typing] Fix type error when passing Mapped columns to values()
This adjusts the _DMLOnlyColumnArgument type to be a more
focused _OnlyColumnArgument type where we also add a more tightly
focused coercion, while still allowing ORM attributes to be used
as arguments.

Co-authored-by: Mike Bayer <mike_mp@zzzcomputing.com>
Closes: #13012
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13012
Pull-request-sha: 5ebb402c68

Change-Id: I8bbccaf556ec5ecb2f5cfdd2030bcfa4eb5ce125
2025-12-02 22:37:57 -05:00
Mike Bayer d723e235c0 doc updates
Change-Id: I60bccf962e4cd1ed567a772c43c969c4807662f6
2025-12-02 20:06:50 -05:00
Federico Caselli 0e8920770a Merge "Add native BOOLEAN type support for Oracle 23c and later versions" into main 2025-12-02 21:51:25 +00:00
Federico Caselli 521fd85a3f Merge "Type postgresql.ExcludeConstraint()" into main 2025-12-02 19:45:15 +00:00
Yeongbae Jeon 6baf3b9fb2 Add native BOOLEAN type support for Oracle 23c and later versions
Added support for native BOOLEAN support in Oracle Database 23c and above.
The Oracle dialect now renders ``BOOLEAN`` automatically when
:class:`.Boolean` is used in DDL, and also now supports direct use of the
:class:`.BOOLEAN` datatype, when 23c and above is in use.  For Oracle
versions prior to 23c, boolean values continue to be emulated using
SMALLINT as before.   Special case handling is also present to ensure a
SMALLINT that's interpreted with the :class:`.Boolean` datatype on Oracle
Database 23c and above continues to return bool values. Pull request
courtesy Yeongbae Jeon.

Co-authored-by: Mike Bayer <mike_mp@zzzcomputing.com>
Fixes: #11633
Closes: #13000
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13000
Pull-request-sha: 65b8a2c92f

Change-Id: I13be32f6bad5d918f6c7c9622f0deae78f5c6551
2025-12-02 08:25:33 -05:00
Mike Bayer 259636fabb remove sqlalchemy ML
Change-Id: I85fbdd8b2b3e5ae0c3a99e98f942865d92351f2f
2025-12-01 18:20:02 -05:00
Mike Bayer 6a7d40ffb5 add wheels for python 3.14
Change-Id: Ia69c9e728e38622d643752b61b0627b3baae5089
2025-12-01 15:21:58 -05:00
Denis Laxalde 4f87f4d926 Type postgresql.ExcludeConstraint()
Related to #6810.

Closes: #13011
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13011
Pull-request-sha: 4a212cad1b

Change-Id: If5d91e06b6c0afc11adc02bb0c0d5ce97e53203c
2025-12-01 05:43:18 -05:00
Mike Bayer b9e3cacb0e add TString support
Added support for Python 3.14+ template strings (t-strings) via the new
:func:`_sql.tstring` construct, as defined in :pep:`750`. This feature
allows for ergonomic SQL statement construction by automatically
interpolating Python values and SQLAlchemy expressions within template
strings.

Part of the challenge here is the syntax only works on py314, so we have
to exclude the test file at many levels when py314 is not used.  not
sure yet how i want to adjust pep8 tests and rules for this.

Fixes: #12548
Change-Id: Ia060d1387ff452fe4f5d924f683529a22a8e1f72
2025-11-30 14:38:13 -05:00
Mike Bayer 6dbd980df0 use oracledb as default in setup, update URLs
part of 🎫`13010`, as CI is now oracledb centric
move setup.cfg / pyproject installs / URLs to be oracledb first.
use 23c URLs now that we are on this platform.

Change-Id: I1253c76c382637987e67e36b3d5c82081cd306a8
2025-11-30 11:39:04 -05:00
Mike Bayer 2169a29504 additional fixes re: mariadb innodb etc.
fix a bunch of side effects that were not tested in the gerrit
phase because we run with --backendonly

Change-Id: Iebcedb962e6e11dd247b0da5f309a71db711694c
2025-11-28 22:47:40 -05:00
Mike Bayer 3d6a109c83 drop a 400 ton anvil on oracle 23c
this DB is extremely erratic in being able to connect.   Add
a brute force connection retrier to all engines everywhere
(which for oracledb we can fortunately use their built-in feature
that also works).
This actually works and I can see it pausing under load, reconnecting,
and succeeding.  the problem is that absolutely every engine everywhere
needs this routine otherwise an engine without a retrier in it will
crash.    That then necessitates digging into testing_engine(),
making sure testing_engine() is used everywhere an engine that's going
to connect is used, then dealing with the fallout from that.

We also simplify some older workarounds for cx_oracle and
hack into config/provision to make oracledb seem like the primary
DBAPI for most tests.

testing_engine has been completely overhauled, making use of a new
post_configure_testing_engine() hook which moves and refines
the SQLite pool sharing and savepoint logic all into sqlite/provision.py
and also allows for cx_oracle to apply a retry event handler.

Change-Id: I4ea4c523effb878290d28b94d8925eb32fc5ae3b
2025-11-28 13:16:13 -05:00
Mike Bayer 0260f7e58b happy mypy day
Change-Id: Ic72aeea508e73344927692f62332b2b62a8cbdea
2025-11-28 11:48:22 -05:00
Mike Bayer 0b8e3dd062 delete cython in place files before running pep8
slotscheck otherwise can get confused if there are stale
.so files present

Change-Id: Ic855101f7ad6c92d2404331408ca6f02db0c49be
2025-11-27 11:32:32 -05:00
Michael Bayer 4affeefb34 Merge "stop using MyISAM; more oracle struggles" into main 2025-11-27 04:40:35 +00:00
Mike Bayer 8802895457 stop using MyISAM; more oracle struggles
getting some fails on mariadb12 and likely 11 which appear to
be related to calling in MyISAM, which is not used in
modern mysql/mariadb.   see if we can just remove this whole
thing and rely on default engines for mariadb/mysql.

this change also removes the "ignore errors" part of the
run deletes for the TablesTest fixture, which was resulting
in compound failures, and apparently a lot of tests were relying
on it skipping nonexistent tables.   rather than check for that
we should just improve the tests and probably increase use of
pytest style fixtures overall.

this change also identifies and fixes that memusage_w_backend
tests were running for all backends with a tag like
py314_mysql_backendonly; the memusage tests should basically
never be run as part of the whole suite since they are entirely
unreliable within a full scale test run.

dialect suite tests are also further broken out into those where
every driver should be exercised (i.e. __backend__, for tests that
test datatypes going out and coming back from the database as well
as identity/autoincrement kinds of tests) vs. those where only
one driver per backend is needed (i.e. __sparse_driver_backend__,
for tests like reflection, DDL, CTEs, etc.).

we are also trying to get a --low-connections option that actually
works.  changed this so that the testing reaper aggressively disposes
the "global" engines (one per backend / driver) after test classes
are done and before any testing_engine() call.   This definitely
works, however some monitoring with PG shows the number of connections
still has brief bursts for some reason.   it should be much more
effective than before though as oracle 23/26 really does not handle
more than a few connections.

this change reverts oracle to oracle18c for now in setup.cfg;
further work will be needed to determine if oracle23c can be
run with this test suite

Change-Id: Id87d0ea15155c452615a7edeb9d434c8e55151e7
2025-11-26 22:24:28 -05:00
Federico Caselli 09ce4d0754 re-enable vectore test in oracle
Change-Id: I382a20027f36f32617d2680332873f1b7d5bcee6
2025-11-25 22:48:01 +01:00
Mike Bayer cf62005639 test oracle 23c, mariadb12; reduce backend use
one particular vector test wont run on oracle 23c free, so
just disable it.

added better skips for the rest of the vector tests and
fixed a deprecation issue.

this will be the first run on the new oracle23 on CI so we'll have to
see how this goes.

Also adjust for mariabdb12 being overly helpful with regards
to stale row updates.

as we are having trouble getting 23c to pass throug transaction
tests, i noted we have an explosion of tests due to the multiple
drivers, so this patch introduces __sparse_driver_backend__
for all tests where we want variety of
database server but there's no need to test every driver.
This should dramatically reduce the size of the test suite run

Change-Id: Ic8d3eb0a60e76b4c54c6bb4a721f90c81ede782b
2025-11-25 14:50:56 -05:00
Mike Bayer 871e66e058 break up test_update_delete_where into several files
it's grown to 3K lines and i need to add more tests

Change-Id: Ic55c50446d57789e3e3cc58e6a99239c1bfa8328
2025-11-21 13:45:45 -05:00
Shamil 6ee4d884f0 Fix parameter mutation in orm_pre_session_exec()
The :meth:`_events.SessionEvents.do_orm_execute` event now allows direct
mutation or replacement of the :attr:`.ORMExecuteState.parameters`
dictionary or list, which will take effect when the the statement is
executed.  Previously, changes to this collection were not accommodated by
the event hook.  Pull request courtesy Shamil.

Fixes: #12921
Closes: #12989
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/12989
Pull-request-sha: 86b64e0617

Change-Id: I04874b6ca720eb2be1470067ced4afd79896e267
2025-11-20 14:18:35 -05:00
Mike Bayer 708a0360b1 use zimports 0.7.0
this adds pyproject.toml support

Change-Id: I6d00fc912f25405542326c3d0ffcfb1969cea24b
2025-11-20 13:45:08 -05:00
Shamil a057c474bf Fix type hint for with_for_update() to support tuples of table classes
Fixed typing issue where :meth:`.Select.with_for_update` would not support
lists of ORM entities in the :paramref:`.Select.with_for_update.of`
parameter. Pull request courtesy Shamil.

Fixes: #12730
Closes: #12988
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/12988
Pull-request-sha: 41a38bfe38

Change-Id: I61d60a4f4d2b16037da8d5f30e33f5d74fa47374
2025-11-19 09:04:04 -05:00
Mike Bayer deff837bde use py3.14 for pep484/pep8
since we updated this recently

Change-Id: I25fe3dae099aca608798b7d28b952855acda230f
2025-11-18 17:24:45 -05:00
Mike Bayer 42710c9220 propagate _scalar_type() for SelectStatementGrouping
Fixed issue where using the :meth:`.ColumnOperators.in_` operator with a
nested :class:`.CompoundSelect` statement (e.g. an ``INTERSECT`` of
``UNION`` queries) would raise a :class:`NotImplementedError` when the
nested compound select was the first argument to the outer compound select.
The ``_scalar_type()`` internal method now properly handles nested compound
selects.

Fixes: #12987
Change-Id: I6aa1b38863588d371bbac74b3531b99ccd5fcaec
2025-11-18 15:11:05 -05:00
Mike Bayer f6714c8e09 update lint setup
We are stuck on flake8 because we rely on many plugins with
specific behaviors.  The situation has calcified where:

1. the whole world uses ruff
2. nobody cares about import order linting or all the other stuff
   we do, and/or similar but not quite the same things are embedded
   deeply into ruff which would require us giving up a lot of our
   standards (like isort)
3. flake8 is absolutely never going to support pyproject.
4. flake8-pyproject works for this

beyond that, for t string support we want to make it easy
to get onto py3.14, so here we update black to the latest which
appears to fix some missing symbols for py3.14 t strings.

we should also migrate the remaining sqlalchemy test config
from setup.cfg to pyproject.toml but that should likely be
2.1 only

Change-Id: I896a7c839148d0ef516728c73baddc8eddf5ee96
2025-11-17 17:16:52 -05:00
Mike Bayer 5af013026f add highlight for python3 over api doc sections
the pycon+sql highlight seems to take effect for docstrings
now in sphinx 8 or whatever.

Fixes: #12981
Change-Id: Ifab2c66d6adddf3ce5336f244653a336ac0d2ce9
2025-11-16 10:58:27 -05:00
Federico Caselli 850f7ae12e Add DictBundle
Added :class:`_orm.DictBundle` as a subclass of :class:`_orm.Bundle`
that returns ``dict`` objects.

Fixes: #12960
Change-Id: I798fb917779eb95bda575f2809e58c2f6d3c4706
2025-11-15 18:33:07 +00:00
Mike Bayer 8383e3f48c add pyv to file template; use = for all custom args
adding "test/" to pytest doesnt work because then we can't indicate
a specific set of test files.  use = for all sqlalchemy-custom
parameters instead to avoid [1]

[1] https://github.com/pytest-dev/pytest/issues/13913

Change-Id: I9eb5bbfac734fcb145fcf3ae58fcc55df6bb6e71
2025-11-15 11:36:56 -05:00
Albert N 95ab6ed79c perf tuning of BaseRow
common cases are a bit faster overall

Python version
|                      | python opt | python main | py opt / main |
| -------------------- | ---------- | ----------- | ------------- |
| base_row_new         | 0.84959    | 0.86417     | 0.9831283197  |
| row_new              | 0.85698    | 0.85543     | 1.001811954   |
| base_row_new_proc    | 2.77489    | 2.81795     | 0.9847193882  |
| row_new_proc         | 2.77881    | 2.86206     | 0.9709125595  |
| brow_new_proc_none   | 1.6311     | 1.65773     | 0.9839358641  |
| row_new_proc_none    | 1.65048    | 1.69896     | 0.9714648962  |
| row_dumps            | 0.15279    | 0.14519     | 1.052345203   |
| row_loads            | 0.91471    | 0.91358     | 1.001236892   |
| row_values_impl      | 0.1818     | 0.17773     | 1.022899904   |
| row_iter             | 0.44042    | 0.4554      | 0.967105841   |
| row_len              | 0.13858    | 0.13079     | 1.059561129   |
| row_hash             | 0.28614    | 0.29172     | 0.9808720691  |
| getitem              | 0.23159    | 0.23138     | 1.000907598   |
| getitem_slice        | 0.38393    | 0.38765     | 0.9904037147  |
| get_by_key           | 0.33692    | 0.33913     | 0.993483325   |
| get_by_key2          | 0.35105    | 0.33915     | 1.035087719   |
| getattr              | 0.46809    | 0.46911     | 0.9978256699  |
| get_by_key_recreate  | 1.08137    | 1.18224     | 0.9146789146  |
| get_by_key_recreate2 | 0.98543    | 0.99272     | 0.9926565396  |
| getattr_recreate     | 0.74       | 0.7407      | 0.999054948   |
| contains             | 0.49312    | 0.74477     | 0.6621104502  |

Cython version
|                      | cython opt | cython main | cy opt / main |
| -------------------- | ---------- | ----------- | ------------- |
| base_row_new         | 0.12933    | 0.1347      | 0.9601336303  |
| row_new              | 0.15755    | 0.16489     | 0.9554854752  |
| base_row_new_proc    | 0.87398    | 1.08483     | 0.8056377497  |
| row_new_proc         | 0.88592    | 1.13255     | 0.7822347799  |
| brow_new_proc_none   | 0.2664     | 0.41703     | 0.6388029638  |
| row_new_proc_none    | 0.27526    | 0.42483     | 0.6479297601  |
| row_dumps            | 0.37526    | 0.20093     | 1.867615588   |
| row_loads            | 0.53037    | 0.3607      | 1.470390907   |
| row_values_impl      | 0.36886    | 0.22218     | 1.660185435   |
| row_iter             | 0.25249    | 0.25553     | 0.9881031581  |
| row_len              | 0.05194    | 0.05412     | 0.9597191426  |
| row_hash             | 0.18864    | 0.18726     | 1.007369433   |
| getitem              | 0.13876    | 0.13934     | 0.9958375197  |
| getitem_slice        | 0.23181    | 0.2318      | 1.000043141   |
| get_by_key           | 0.17031    | 0.17857     | 0.9537436299  |
| get_by_key2          | 0.58172    | 0.31651     | 1.837919813   |
| getattr              | 0.21275    | 1.16669     | 0.1823534958  |
| get_by_key_recreate  | 0.80161    | 0.8836      | 0.9072091444  |
| get_by_key_recreate2 | 1.14649    | 0.98709     | 1.161484768   |
| getattr_recreate     | 0.55927    | 1.09921     | 0.5087926784  |
| contains             | 0.35338    | 0.5494      | 0.6432107754  |

Closes: #12919
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/12919
Pull-request-sha: b13204b741

Change-Id: I5ff2b951f9840e99abdad3ae286ecb8becc70e4b
2025-11-13 23:59:59 +01:00
Fredrik Ålund d96c04950d Add Mimer SQL to list of external dialects (#12969) 2025-11-13 00:05:21 +01:00