Change8

rel_2_0_52

📦 sqlalchemyView on GitHub →
1 features🐛 11 fixes1 deprecations🔧 24 symbols

Summary

This release adds Python 3.15 support and includes numerous bug fixes across ORM, SQL, schema, and PostgreSQL components. Key fixes address result-column misalignment, session flushing states, unpickling issues, and reflection of PostgreSQL CHECK constraints.

Migration Steps

  1. Under SQLAlchemy 2.1, replace calls to `_orm.aliased()` with `_sql.select()` or `_sql.union()` / `_sql.CompoundSelect` constructs with a subquery.
  2. For PostgreSQL, use the new construct replacing the expression argument to `_sql.Select.distinct()` if you are on SQLAlchemy 2.1.

✨ New Features

  • Python 3.15 support has been added and tested.

🐛 Bug Fixes

  • Fixed a result-column misalignment bug in ORM-enabled UPDATE statements where `synchronize_session="fetch"` is in use. Columns in rows returned by `.returning()` could be returned under incorrect keys.
  • Fixed bug where a failed `_orm.Session.bulk_insert_mappings()`, `_orm.Session.bulk_update_mappings()` or `_orm.Session.bulk_save_objects()` call could leave the `_orm.Session` permanently in a "flushing" state.
  • Fixed issue where unpickling an ORM object loaded using loader options with wildcard tokens (e.g., `_orm.load_only()` or `_orm.raiseload()` with "*") would fail with `KeyError` or `IndexError` if the unpickling process had not yet constructed a loader path using that same token.
  • Fixed issue where a string ending in `"*"` passed to a `_orm.Load` strategy method would bypass the check that rejects string attribute names in loader options, silently producing a loader path that matched nothing. Such a string now raises `ArgumentError`.
  • Fixed issue where using PEP 593 `Annotated` wrapping a PEP 695 `type` alias would crash with `AttributeError: __value__` due to an incorrect `is_pep695()` check.
  • Fixed issue where `_sql.Select.get_final_froms()` would emit a deprecation warning when the statement used the PostgreSQL-specific expression argument to `_sql.Select.distinct()`; the same spurious warning would be emitted when stringifying such a statement without explicitly using a PostgreSQL dialect.
  • Fixed an issue in `Numeric` where the `Numeric.decimal_return_scale` parameter was ignored when the DBAPI does not support native decimal objects. The result processor was computing the conversion scale from `Numeric.scale` directly.
  • Added auditing to the test suite to ensure string input is either appropriately rejected or correctly escaped for literal execute processors across all datatypes and dialects. Updated SQL Server `Uuid` / `UNIQUEIDENTIFIER` rendering, `JSONPATH` type, and numeric types.
  • Fixed an issue where `_schema.Table.to_metadata()` reused column default and on-update objects, causing the defaults on the original columns to refer to the copied columns. Default generators are now copied and remain associated with their respective columns.
  • Fixed reflection of PostgreSQL CHECK constraints where an expression made up of multiple parenthesized sub-expressions would have its leading and trailing parentheses incorrectly stripped.
  • Fixed bug in the PostgreSQL dialect where a single quote in a sequence, table, or schema name would cause issues.

Affected Symbols

⚡ Deprecations

  • Calling `_orm.aliased()` against a `_sql.select()` or `_sql.union()` / `_sql.CompoundSelect` construct now raises an error under SQLAlchemy 2.1, and emits a deprecation warning under SQLAlchemy 2.0. This is because the construct is coerced into a subquery, matching the behavior of other similar implicit SELECT-to-FROM coercions.