Mike Bayer [Mon, 12 May 2025 19:25:07 +0000 (15:25 -0400)]
rewrite the docs on SQLite transaction handling
SQLite has added the new "connection.autocommit" mode and
associated fixes for pep-249 as of python 3.12. they plan to
default to using this attribute as of python 3.16. Get
on top of things by rewriting the whole doc section here, removing
old cruft about sqlalchemy isolation levels that was not correct
in any case, update recipes in a more succinct and unified way.
Mike Bayer [Thu, 6 Mar 2025 14:12:43 +0000 (09:12 -0500)]
implement pep-649 workarounds, test suite passing for python 3.14
Changes to the test suite to accommodate Python 3.14 as of version
3.14.0b1
Originally this included a major breaking change to how python 3.14
implemented :pep:`649`, however this was resolved by [1].
As of a7, greenlet is skipped due to issues in a7 and later b1
in [2].
1. the change to rewrite all conditionals in annotation related tests
is reverted.
2. test_memusage needed an explicit set_start_method() call so that
it can continue to use plain fork
3. unfortunately at the moment greenlet has to be re-disabled for 3.14.
4. Changes to tox overall, remove pysqlcipher which hasn't worked
in years, etc.
5. we need to support upcoming typing-extensions also, install the beta
6. 3.14.0a7 introduces major regressions to our runtime typing
utilities, unfortunately, it's not clear if these can be resolved
7. for 3.14.0b1, we have to vendor get_annotations to work around [3]
Justine Krejcha [Tue, 6 May 2025 19:18:02 +0000 (15:18 -0400)]
typing: pg: type NamedType create/drops (fixes #12557)
Type the `create` and `drop` functions for `NamedType`s
Also partially type the SchemaType create/drop functions more generally
One change to this is that the default parameter of `None` is removed. It doesn't work and will fail with a `AttributeError` at runtime since it immediately tries to access a property of `None` which doesn't exist.
Fixes #12557
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.
Mike Bayer [Tue, 6 May 2025 22:06:15 +0000 (18:06 -0400)]
reorganize ORM Annotated Declarative into its own section
The ORM Annotated Declarative section is now very large but has been
indented under the "Declarative Table with mapped_column()" section
where it does not show up well on top level TOCs and is too deeply
nested. Break it out into its own section following the
entire "Declarative Table" section, but also maintain a short intro
section inside of "Declarative Table" to ensure this use is still
prominent.
suraj [Mon, 5 May 2025 15:14:35 +0000 (11:14 -0400)]
Added vector datatype support in Oracle dialect
Added new datatype :class:`_oracle.VECTOR` and accompanying DDL and DQL
support to fully support this type for Oracle Database. This change
includes the base :class:`_oracle.VECTOR` type that adds new type-specific
methods ``l2_distance``, ``cosine_distance``, ``inner_product`` as well as
new parameters ``oracle_vector`` for the :class:`.Index` construct,
allowing vector indexes to be configured, and ``oracle_fetch_approximate``
for the :meth:`.Select.fetch` clause. Pull request courtesy Suraj Shaw.
Mike Bayer [Thu, 1 May 2025 13:43:29 +0000 (09:43 -0400)]
fix sqlite localtimestamp function
Fixed and added test support for a few SQLite SQL functions hardcoded into
the compiler most notably the "localtimestamp" function which rendered with
incorrect internal quoting.
refactor (orm): remove unused variables and simplify key lookups
Redundant variables and unnecessary conditions were removed across several modules. Improved readability and reduced code complexity without changing functionality.
Added support for the pow operator (``**``), with a default SQL
implementation of the ``POW()`` function. On Oracle Database, PostgreSQL
and MSSQL it renders as ``POWER()``. As part of this change, the operator
routes through a new first class ``func`` member :class:`_functions.pow`,
which renders on Oracle Database, PostgreSQL and MSSQL as ``POWER()``.
refactor (sql): simplify and optimize internal SQL handling
Replaced redundant variable assignments with direct operations. Used `dict.get()` for safer dictionary lookups to streamline logic. Improves code readability and reduces unnecessary lines.
refactor(testing-and-utils): Remove unused code and fix style issues
This PR includes several small refactorings and style fixes aimed at improving code cleanliness, primarily within the test suite and tooling.
Key changes:
* Removed assignments to unused variables in various test files (`test_dialect.py`, `test_reflection.py`, `test_select.py`).
* Removed an unused variable in the pytest plugin (`pytestplugin.py`).
* Removed an unused variable in the topological sort utility (`topological.py`).
* Fixed a minor style issue (removed an extra blank line) in the `cython_imports.py` script.
refactor: clean up unused variables in engine module
Removed unused variables to improve code clarity and maintainability. This change simplifies logic in `base.py`, `default.py`, and `result.py`. No functionality was altered.
refactor: simplify and clean up dialect-specific code
**Title:** Removed unused variables and redundant functions across multiple dialects. Improves code readability and reduces maintenance complexity without altering functionality.
### Description
This pull request introduces several minor refactorings across different dialect modules:
- **MSSQL:**
- Simplified the initialization of the `fkeys` dictionary in `_get_foreign_keys` using `util.defaultdict` directly.
- **MySQL:** Removed the unused variable in `_get_table_comment`. `rp`
- **PostgreSQL (_psycopg_common):** Removed the unused variable `cursor` in `do_ping`.
- **PostgreSQL (base):** Removed the unused variable `args` in `_get_column_info`.
- **SQLite:** Removed the unused variable `new_filename` in `generate_driver_url`.
These changes focus purely on code cleanup and simplification, removing dead code and improving clarity. They do not alter the existing logic or functionality of the dialects.
### Checklist
This pull request is:
- [ ] A documentation / typographical / small typing error fix
- [x] A short code fix
- _Note: This is a general cleanup refactor rather than a fix for a specific reported issue._
Mike Bayer [Mon, 21 Apr 2025 13:44:40 +0000 (09:44 -0400)]
disable mysql/connector-python, again
Just as we got this driver "working", a new regression is introduced
in version 9.3.0 which prevents basic binary string persistence [1].
I would say we need to leave this driver off for another few years
until something changes with its upstream maintenance.
Mike Bayer [Tue, 8 Apr 2025 01:41:29 +0000 (21:41 -0400)]
simplify internal storage of DML ordered values
towards some refactorings I will need to do for #12496, this
factors out the "_ordered_values" list of tuples that was used to
track UPDATE VALUES in a specific order. The rationale for this
separate collection was due to Python dictionaries not maintaining
insert order. Now that this is standard behavior in Python 3
we can use the same `statement._values` for param-ordered and
table-column-ordered UPDATE rendering.
$ .venv/bin/python sample.py
add(*(1,), **{'y': 3.14}) => 4.140000000000001
{'x': int | float, 'y': int | float, 'return': int | float}
35.93937499681488 us
mem=9252896, peak=9300808
$ git switch -
Switched to branch 'opt-decorator'
$ .venv/bin/python sample.py
add(*(1,), **{'y': 3.14}) => 4.140000000000001
{'x': int | float, 'y': int | float, 'return': int | float}
23.32574996398762 us
mem=1439032, peak=1476423
```
### 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.
Alexander Ruehe [Tue, 1 Apr 2025 21:52:12 +0000 (17:52 -0400)]
ensure ON UPDATE test is case insensitive
Fixed regression caused by the DEFAULT rendering changes in 2.0.40
:ticket:`12425` where using lowercase `on update` in a MySQL server default
would incorrectly apply parenthesis, leading to errors when MySQL
interpreted the rendered DDL. Pull request courtesy Alexander Ruehe.
Fixed issue where :meth:`.AsyncSession.get_transaction` and
:meth:`.AsyncSession.get_nested_transaction` would fail with
``NotImplementedError`` if the "proxy transaction" used by
:class:`.AsyncSession` were garbage collected and needed regeneration.
Kaan [Wed, 19 Mar 2025 15:58:30 +0000 (11:58 -0400)]
Implement GROUPS frame spec for window functions
Implemented support for the GROUPS frame specification in window functions
by adding :paramref:`_sql.over.groups` option to :func:`_sql.over`
and :meth:`.FunctionElement.over`. Pull request courtesy Kaan Dikmen.
Daraan [Wed, 26 Mar 2025 18:27:46 +0000 (14:27 -0400)]
compatibility with typing_extensions 4.13 and type statement
Fixed regression caused by ``typing_extension==4.13.0`` that introduced
a different implementation for ``TypeAliasType`` while SQLAlchemy assumed
that it would be equivalent to the ``typing`` version.
Federico Caselli [Mon, 24 Mar 2025 20:50:45 +0000 (21:50 +0100)]
improve overloads applied to generic functions
try again to remove the overloads to the generic functionn
generator (like coalesce, array_agg, etc).
As of mypy 1.15 it still does now work, but a simpler version
is added in this change
Denis Laxalde [Mon, 24 Mar 2025 20:35:07 +0000 (16:35 -0400)]
Type array_agg()
The return type of `array_agg()` is declared as a `Sequence[T]` where `T` is bound to the type of input argument.
This is implemented by making `array_agg()` inheriting from `ReturnTypeFromArgs` which provides appropriate overloads of `__init__()` to support this.
This usage of ReturnTypeFromArgs is a bit different from previous ones as the return type of the function is not exactly the same as that of its arguments, but a "collection" (a generic, namely a Sequence here) of the argument types. Accordingly, we adjust the code of `tools/generate_sql_functions.py` to retrieve the "collection" type from 'fn_class' annotation and generate expected return type.
Also add a couple of hand-written typing tests for PostgreSQL.
Denis Laxalde [Wed, 19 Mar 2025 08:17:27 +0000 (04:17 -0400)]
Cast empty PostgreSQL ARRAY from the type specified to array()
When building a PostgreSQL ``ARRAY`` literal using
:class:`_postgresql.array` with an empty ``clauses`` argument, the
:paramref:`_postgresql.array.type_` parameter is now significant in that it
will be used to render the resulting ``ARRAY[]`` SQL expression with a
cast, such as ``ARRAY[]::INTEGER``. Pull request courtesy Denis Laxalde.
Mike Bayer [Wed, 19 Mar 2025 22:30:21 +0000 (18:30 -0400)]
skip FROM disambiguation for immediate alias of table
Fixed regression caused by :ticket:`7471` leading to a SQL compilation
issue where name disambiguation for two same-named FROM clauses with table
aliasing in use at the same time would produce invalid SQL in the FROM
clause with two "AS" clauses for the aliased table, due to double aliasing.
Mike Bayer [Tue, 10 Dec 2024 15:59:25 +0000 (10:59 -0500)]
implement use_descriptor_defaults for dataclass defaults
A significant behavioral change has been made to the behavior of the
:paramref:`_orm.mapped_column.default` and
:paramref:`_orm.relationship.default` parameters, when used with
SQLAlchemy's :ref:`orm_declarative_native_dataclasses` feature introduced
in 2.0, where the given value (assumed to be an immutable scalar value) is
no longer passed to the ``@dataclass`` API as a real default, instead a
token that leaves the value un-set in the object's ``__dict__`` is used, in
conjunction with a descriptor-level default. This prevents an un-set
default value from overriding a default that was actually set elsewhere,
such as in relationship / foreign key assignment patterns as well as in
:meth:`_orm.Session.merge` scenarios. See the full writeup in the
:ref:`whatsnew_21_toplevel` document which includes guidance on how to
re-enable the 2.0 version of the behavior if needed.
This adds a new implicit default field to ScalarAttributeImpl
so that we can have defaults that are not in the dictionary but
are instead passed through to the class-level descriptor, effectively
allowing custom defaults that are not used in INSERT or merge
Mike Bayer [Wed, 19 Mar 2025 12:59:54 +0000 (08:59 -0400)]
remove attrs w/ orm annotated declarative example
as pointed out at
https://github.com/sqlalchemy/sqlalchemy/discussions/12449, ORM
annotated declarative is not compatible with attrs, declarative
cannot be used with attrs.
Denis Laxalde [Tue, 18 Mar 2025 16:23:01 +0000 (12:23 -0400)]
Make ARRAY generic on the item_type
Now `Column(type_=ARRAY(Integer)` is inferred as `Column[Sequence[int]]` instead as `Column[Sequence[Any]]` previously. This only works with the `type_` argument to Column, but that's not new.
This follows from a suggestion at
https://github.com/sqlalchemy/sqlalchemy/pull/12386#issuecomment-2694056069.
Mike Bayer [Mon, 17 Mar 2025 20:46:12 +0000 (16:46 -0400)]
ensure SQL expressions w/o bool pass through to correct typing error
Fixed regression which occurred as of 2.0.37 where the checked
:class:`.ArgumentError` that's raised when an inappropriate type or object
is used inside of a :class:`.Mapped` annotation would raise ``TypeError``
with "boolean value of this clause is not defined" if the object resolved
into a SQL expression in a boolean context, for programs where future
annotations mode was not enabled. This case is now handled explicitly and
a new error message has also been tailored for this case. In addition, as
there are at least half a dozen distinct error scenarios for intepretation
of the :class:`.Mapped` construct, these scenarios have all been unified
under a new subclass of :class:`.ArgumentError` called
:class:`.MappedAnnotationError`, to provide some continuity between these
different scenarios, even though specific messaging remains distinct.
Mike Bayer [Tue, 25 Feb 2025 15:11:29 +0000 (10:11 -0500)]
add postgresql distinct_on (patch 4)
Added syntax extension :func:`_postgresql.distinct_on` to build ``DISTINCT
ON`` clauses. The old api, that passed columns to
:meth:`_sql.Select.distinct`, is now deprecated.
Mike Bayer [Wed, 12 Mar 2025 20:25:48 +0000 (16:25 -0400)]
expand paren rules for default rendering, sqlite/mysql
Expanded the rules for when to apply parenthesis to a server default in DDL
to suit the general case of a default string that contains non-word
characters such as spaces or operators and is not a string literal.
Fixed issue in MySQL server default reflection where a default that has
spaces would not be correctly reflected. Additionally, expanded the rules
for when to apply parenthesis to a server default in DDL to suit the
general case of a default string that contains non-word characters such as
spaces or operators and is not a string literal.
Denis Laxalde [Thu, 13 Mar 2025 12:43:53 +0000 (08:43 -0400)]
Support column list for foreign key ON DELETE SET actions on PostgreSQL
Added support for specifying a list of columns for ``SET NULL`` and ``SET
DEFAULT`` actions of ``ON DELETE`` clause of foreign key definition on
PostgreSQL. Pull request courtesy Denis Laxalde.
Mike Bayer [Mon, 17 Mar 2025 12:53:00 +0000 (08:53 -0400)]
remove non_primary parameter
The "non primary" mapper feature, long deprecated in SQLAlchemy since
version 1.3, has been removed. The sole use case for "non primary"
mappers was that of using :func:`_orm.relationship` to link to a mapped
class against an alternative selectable; this use case is now suited by the
:doc:`relationship_aliased_class` feature.
Denis Laxalde [Fri, 14 Mar 2025 21:01:50 +0000 (17:01 -0400)]
Add type annotations to `postgresql.array`
Improved static typing for `postgresql.array()` by making the type parameter (the type of array's elements) inferred from the `clauses` and `type_` arguments while also ensuring they are consistent.
Also completed type annotations of `postgresql.ARRAY` following commit 0bf7e02afbec557eb3a5607db407f27deb7aac77 and added type annotations for functions `postgresql.Any()` and `postgresql.All()`.
Finally, fixed shadowing `typing.Any` by the `Any()` function through aliasing as `typing_Any`.
Mike Bayer [Fri, 14 Mar 2025 14:33:22 +0000 (10:33 -0400)]
anonymize CRUD params if visiting_cte is present
Fixed issue in :class:`.CTE` constructs involving multiple DDL
:class:`.Insert` statements with multiple VALUES parameter sets where the
bound parameter names generated for these parameter sets would conflict,
generating a compile time error.
Mike Bayer [Thu, 13 Mar 2025 14:26:50 +0000 (10:26 -0400)]
callcount updates
not clear why this isn't happening on all py312s but this adjust
profiles for some memory changes that have occurred as of 88b77c8b19523e15d3595b0a58 - just the merge change, not the actual
code change for whatever reason. very strange