--- /srv/reproducible-results/rbuild-debian/r-b-build.nKylx3QQ/b1/sqlalchemy_2.0.32+ds1-1_armhf.changes +++ /srv/reproducible-results/rbuild-debian/r-b-build.nKylx3QQ/b2/sqlalchemy_2.0.32+ds1-1_armhf.changes ├── Files │ @@ -1,5 +1,5 @@ │ │ - 0edf423a1d39fac3689b73a709c826ea 3956520 doc optional python-sqlalchemy-doc_2.0.32+ds1-1_all.deb │ + 3c52278352fb66b47af3ed26d609928f 3956224 doc optional python-sqlalchemy-doc_2.0.32+ds1-1_all.deb │ 9fabb2a962b8bd7da2eceef5e38e1c7f 902280 debug optional python3-sqlalchemy-ext-dbgsym_2.0.32+ds1-1_armhf.deb │ 2b30c02f46036b453f048fc47e70fa6d 123428 python optional python3-sqlalchemy-ext_2.0.32+ds1-1_armhf.deb │ 0955e7f12a0b73c1ab8406c88fbab7d2 1196068 python optional python3-sqlalchemy_2.0.32+ds1-1_all.deb ├── python-sqlalchemy-doc_2.0.32+ds1-1_all.deb │ ├── file list │ │ @@ -1,3 +1,3 @@ │ │ -rw-r--r-- 0 0 0 4 2024-08-23 07:52:58.000000 debian-binary │ │ --rw-r--r-- 0 0 0 13920 2024-08-23 07:52:58.000000 control.tar.xz │ │ --rw-r--r-- 0 0 0 3942408 2024-08-23 07:52:58.000000 data.tar.xz │ │ +-rw-r--r-- 0 0 0 13928 2024-08-23 07:52:58.000000 control.tar.xz │ │ +-rw-r--r-- 0 0 0 3942104 2024-08-23 07:52:58.000000 data.tar.xz │ ├── control.tar.xz │ │ ├── control.tar │ │ │ ├── ./md5sums │ │ │ │ ├── ./md5sums │ │ │ │ │┄ Files differ │ ├── data.tar.xz │ │ ├── data.tar │ │ │ ├── ./usr/share/doc/python-sqlalchemy-doc/html/changelog/changelog_10.html │ │ │ │ @@ -592,15 +592,15 @@ │ │ │ │
│ │ │ │

1.0 Changelog

│ │ │ │
│ │ │ │

1.0.19

│ │ │ │ Released: August 3, 2017
│ │ │ │

oracle

│ │ │ │
    │ │ │ │ -
  • [oracle] [performance] [bug] [py2k]

    Fixed performance regression caused by the fix for #3937 where │ │ │ │ +

  • [oracle] [bug] [performance] [py2k]

    Fixed performance regression caused by the fix for #3937 where │ │ │ │ cx_Oracle as of version 5.3 dropped the .UNICODE symbol from its │ │ │ │ namespace, which was interpreted as cx_Oracle’s “WITH_UNICODE” mode being │ │ │ │ turned on unconditionally, which invokes functions on the SQLAlchemy │ │ │ │ side which convert all strings to unicode unconditionally and causing │ │ │ │ a performance impact. In fact, per cx_Oracle’s author the │ │ │ │ “WITH_UNICODE” mode has been removed entirely as of 5.1, so the expensive unicode │ │ │ │ conversion functions are no longer necessary and are disabled if │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -318,15 +318,15 @@ │ │ │ │ │ # _o_r_a_c_l_e │ │ │ │ │ # _t_e_s_t_s │ │ │ │ │ # _m_i_s_c │ │ │ │ │ ************ 11..00 CChhaannggeelloogg_?¶ ************ │ │ │ │ │ ********** 11..00..1199_?¶ ********** │ │ │ │ │ Released: August 3, 2017 │ │ │ │ │ ******** oorraaccllee_?¶ ******** │ │ │ │ │ - * [[oorraaccllee]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] [[ppyy22kk]] _¶ │ │ │ │ │ + * [[oorraaccllee]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] [[ppyy22kk]] _¶ │ │ │ │ │ Fixed performance regression caused by the fix for _#_3_9_3_7 where cx_Oracle │ │ │ │ │ as of version 5.3 dropped the .UNICODE symbol from its namespace, which │ │ │ │ │ was interpreted as cx_Oracle’s “WITH_UNICODE” mode being turned on │ │ │ │ │ unconditionally, which invokes functions on the SQLAlchemy side which │ │ │ │ │ convert all strings to unicode unconditionally and causing a performance │ │ │ │ │ impact. In fact, per cx_Oracle’s author the “WITH_UNICODE” mode has been │ │ │ │ │ removed entirely as of 5.1, so the expensive unicode conversion functions │ │ │ ├── ./usr/share/doc/python-sqlalchemy-doc/html/changelog/changelog_11.html │ │ │ │ @@ -875,15 +875,15 @@ │ │ │ │

│ │ │ │
│ │ │ │
│ │ │ │

1.1.13

│ │ │ │ Released: August 3, 2017
│ │ │ │

oracle

│ │ │ │
    │ │ │ │ -
  • [oracle] [performance] [bug] [py2k]

    Fixed performance regression caused by the fix for #3937 where │ │ │ │ +

  • [oracle] [bug] [performance] [py2k]

    Fixed performance regression caused by the fix for #3937 where │ │ │ │ cx_Oracle as of version 5.3 dropped the .UNICODE symbol from its │ │ │ │ namespace, which was interpreted as cx_Oracle’s “WITH_UNICODE” mode being │ │ │ │ turned on unconditionally, which invokes functions on the SQLAlchemy │ │ │ │ side which convert all strings to unicode unconditionally and causing │ │ │ │ a performance impact. In fact, per cx_Oracle’s author the │ │ │ │ “WITH_UNICODE” mode has been removed entirely as of 5.1, so the expensive unicode │ │ │ │ conversion functions are no longer necessary and are disabled if │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -496,15 +496,15 @@ │ │ │ │ │ the same PRECEDING or FOLLOWING keywords in a range by allowing for the │ │ │ │ │ left side of the range to be positive and for the right to be negative, │ │ │ │ │ e.g. (1, 3) is “1 FOLLOWING AND 3 FOLLOWING”. │ │ │ │ │ References: _#_4_0_5_3 │ │ │ │ │ ********** 11..11..1133_?¶ ********** │ │ │ │ │ Released: August 3, 2017 │ │ │ │ │ ******** oorraaccllee_?¶ ******** │ │ │ │ │ - * [[oorraaccllee]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] [[ppyy22kk]] _¶ │ │ │ │ │ + * [[oorraaccllee]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] [[ppyy22kk]] _¶ │ │ │ │ │ Fixed performance regression caused by the fix for _#_3_9_3_7 where cx_Oracle │ │ │ │ │ as of version 5.3 dropped the .UNICODE symbol from its namespace, which │ │ │ │ │ was interpreted as cx_Oracle’s “WITH_UNICODE” mode being turned on │ │ │ │ │ unconditionally, which invokes functions on the SQLAlchemy side which │ │ │ │ │ convert all strings to unicode unconditionally and causing a performance │ │ │ │ │ impact. In fact, per cx_Oracle’s author the “WITH_UNICODE” mode has been │ │ │ │ │ removed entirely as of 5.1, so the expensive unicode conversion functions │ │ │ ├── ./usr/share/doc/python-sqlalchemy-doc/html/changelog/changelog_12.html │ │ │ │ @@ -2977,15 +2977,15 @@ │ │ │ │

    │ │ │ │
  • │ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │

oracle

│ │ │ │
    │ │ │ │ -
  • [oracle] [performance] [bug] [py2k]

    Fixed performance regression caused by the fix for #3937 where │ │ │ │ +

  • [oracle] [bug] [performance] [py2k]

    Fixed performance regression caused by the fix for #3937 where │ │ │ │ cx_Oracle as of version 5.3 dropped the .UNICODE symbol from its │ │ │ │ namespace, which was interpreted as cx_Oracle’s “WITH_UNICODE” mode being │ │ │ │ turned on unconditionally, which invokes functions on the SQLAlchemy │ │ │ │ side which convert all strings to unicode unconditionally and causing │ │ │ │ a performance impact. In fact, per cx_Oracle’s author the │ │ │ │ “WITH_UNICODE” mode has been removed entirely as of 5.1, so the expensive unicode │ │ │ │ conversion functions are no longer necessary and are disabled if │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -1879,15 +1879,15 @@ │ │ │ │ │ verify the number of rows affected on a target version. │ │ │ │ │ [[mmssssqqll]] [[bbuugg]] _¶ │ │ │ │ │ Added a rule to SQL Server index reflection to ignore the so-called “heap” │ │ │ │ │ index that is implicitly present on a table that does not specify a clustered │ │ │ │ │ index. │ │ │ │ │ References: _#_4_0_5_9 │ │ │ │ │ ******** oorraaccllee_?¶ ******** │ │ │ │ │ - * [[oorraaccllee]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] [[ppyy22kk]] _¶ │ │ │ │ │ + * [[oorraaccllee]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] [[ppyy22kk]] _¶ │ │ │ │ │ Fixed performance regression caused by the fix for _#_3_9_3_7 where cx_Oracle │ │ │ │ │ as of version 5.3 dropped the .UNICODE symbol from its namespace, which │ │ │ │ │ was interpreted as cx_Oracle’s “WITH_UNICODE” mode being turned on │ │ │ │ │ unconditionally, which invokes functions on the SQLAlchemy side which │ │ │ │ │ convert all strings to unicode unconditionally and causing a performance │ │ │ │ │ impact. In fact, per cx_Oracle’s author the “WITH_UNICODE” mode has been │ │ │ │ │ removed entirely as of 5.1, so the expensive unicode conversion functions │ │ │ ├── ./usr/share/doc/python-sqlalchemy-doc/html/changelog/changelog_13.html │ │ │ │ @@ -1803,30 +1803,30 @@ │ │ │ │

    │ │ │ │
  • │ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │

oracle

│ │ │ │
    │ │ │ │ -
  • [oracle] [performance] [bug]

    Changed the implementation of fetching CLOB and BLOB objects to use │ │ │ │ +

  • [oracle] [bug]

    Some modifications to how the cx_oracle dialect sets up per-column │ │ │ │ +outputtype handlers for LOB and numeric datatypes to adjust for potential │ │ │ │ +changes coming in cx_Oracle 8.

    │ │ │ │ +

    References: #5246

    │ │ │ │ +

    │ │ │ │ +
  • │ │ │ │ +
  • [oracle] [bug] [performance]

    Changed the implementation of fetching CLOB and BLOB objects to use │ │ │ │ cx_Oracle’s native implementation which fetches CLOB/BLOB objects inline │ │ │ │ with other result columns, rather than performing a separate fetch. As │ │ │ │ always, this can be disabled by setting auto_convert_lobs to False.

    │ │ │ │

    As part of this change, the behavior of a CLOB that was given a blank │ │ │ │ string on INSERT now returns None on SELECT, which is now consistent with │ │ │ │ that of VARCHAR on Oracle.

    │ │ │ │

    References: #5314

    │ │ │ │

    │ │ │ │
  • │ │ │ │ -
  • [oracle] [bug]

    Some modifications to how the cx_oracle dialect sets up per-column │ │ │ │ -outputtype handlers for LOB and numeric datatypes to adjust for potential │ │ │ │ -changes coming in cx_Oracle 8.

    │ │ │ │ -

    References: #5246

    │ │ │ │ -

    │ │ │ │ -
  • │ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │

misc

│ │ │ │
    │ │ │ │
  • [change] [firebird]

    Adjusted dialect loading for firebird:// URIs so the external │ │ │ │ sqlalchemy-firebird dialect will be used if it has been installed, │ │ │ │ @@ -2204,15 +2204,15 @@ │ │ │ │

    misc

    │ │ │ │
      │ │ │ │
    • [usecase] [ext]

      Added keyword arguments to the MutableList.sort() function so that a │ │ │ │ key function as well as the “reverse” keyword argument can be provided.

      │ │ │ │

      References: #5114

      │ │ │ │

      │ │ │ │
    • │ │ │ │ -
    • [performance] [bug]

      Revised an internal change to the test system added as a result of │ │ │ │ +

    • [bug] [performance]

      Revised an internal change to the test system added as a result of │ │ │ │ #5085 where a testing-related module per dialect would be loaded │ │ │ │ unconditionally upon making use of that dialect, pulling in SQLAlchemy’s │ │ │ │ testing framework as well as the ORM into the module import space. This │ │ │ │ would only impact initial startup time and memory to a modest extent, │ │ │ │ however it’s best that these additional modules aren’t reverse-dependent on │ │ │ │ straight Core usage.

      │ │ │ │

      References: #5180

      │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -1144,28 +1144,28 @@ │ │ │ │ │ References: _#_5_2_5_5 │ │ │ │ │ [[mmssssqqll]] [[bbuugg]] [[rreefflleeccttiioonn]] _¶ │ │ │ │ │ Fix a regression introduced by the reflection of computed column in MSSQL when │ │ │ │ │ using SQL server versions before 2012, which does not support the concat │ │ │ │ │ function. │ │ │ │ │ References: _#_5_2_7_1 │ │ │ │ │ ******** oorraaccllee_?¶ ******** │ │ │ │ │ - * [[oorraaccllee]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] _¶ │ │ │ │ │ - Changed the implementation of fetching CLOB and BLOB objects to use │ │ │ │ │ - cx_Oracle’s native implementation which fetches CLOB/BLOB objects inline │ │ │ │ │ - with other result columns, rather than performing a separate fetch. As │ │ │ │ │ - always, this can be disabled by setting auto_convert_lobs to False. │ │ │ │ │ - As part of this change, the behavior of a CLOB that was given a blank │ │ │ │ │ - string on INSERT now returns None on SELECT, which is now consistent with │ │ │ │ │ - that of VARCHAR on Oracle. │ │ │ │ │ - References: _#_5_3_1_4 │ │ │ │ │ -[[oorraaccllee]] [[bbuugg]] _¶ │ │ │ │ │ -Some modifications to how the cx_oracle dialect sets up per-column outputtype │ │ │ │ │ -handlers for LOB and numeric datatypes to adjust for potential changes coming │ │ │ │ │ -in cx_Oracle 8. │ │ │ │ │ -References: _#_5_2_4_6 │ │ │ │ │ + * [[oorraaccllee]] [[bbuugg]] _¶ │ │ │ │ │ + Some modifications to how the cx_oracle dialect sets up per-column │ │ │ │ │ + outputtype handlers for LOB and numeric datatypes to adjust for potential │ │ │ │ │ + changes coming in cx_Oracle 8. │ │ │ │ │ + References: _#_5_2_4_6 │ │ │ │ │ +[[oorraaccllee]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] _¶ │ │ │ │ │ +Changed the implementation of fetching CLOB and BLOB objects to use cx_Oracle’s │ │ │ │ │ +native implementation which fetches CLOB/BLOB objects inline with other result │ │ │ │ │ +columns, rather than performing a separate fetch. As always, this can be │ │ │ │ │ +disabled by setting auto_convert_lobs to False. │ │ │ │ │ +As part of this change, the behavior of a CLOB that was given a blank string on │ │ │ │ │ +INSERT now returns None on SELECT, which is now consistent with that of VARCHAR │ │ │ │ │ +on Oracle. │ │ │ │ │ +References: _#_5_3_1_4 │ │ │ │ │ ******** mmiisscc_?¶ ******** │ │ │ │ │ * [[cchhaannggee]] [[ffiirreebbiirrdd]] _¶ │ │ │ │ │ Adjusted dialect loading for firebird:// URIs so the external sqlalchemy- │ │ │ │ │ firebird dialect will be used if it has been installed, otherwise fall │ │ │ │ │ back to the (now deprecated) internal Firebird dialect. │ │ │ │ │ References: _#_5_2_7_8 │ │ │ │ │ ********** 11..33..1166_?¶ ********** │ │ │ │ │ @@ -1409,15 +1409,15 @@ │ │ │ │ │ but owned by someone else. Pull request courtesy Dave Hirschfeld. │ │ │ │ │ References: _#_5_1_4_6 │ │ │ │ │ ******** mmiisscc_?¶ ******** │ │ │ │ │ * [[uusseeccaassee]] [[eexxtt]] _¶ │ │ │ │ │ Added keyword arguments to the _M_u_t_a_b_l_e_L_i_s_t_._s_o_r_t_(_) function so that a key │ │ │ │ │ function as well as the “reverse” keyword argument can be provided. │ │ │ │ │ References: _#_5_1_1_4 │ │ │ │ │ -[[ppeerrffoorrmmaannccee]] [[bbuugg]] _¶ │ │ │ │ │ +[[bbuugg]] [[ppeerrffoorrmmaannccee]] _¶ │ │ │ │ │ Revised an internal change to the test system added as a result of _#_5_0_8_5 where │ │ │ │ │ a testing-related module per dialect would be loaded unconditionally upon │ │ │ │ │ making use of that dialect, pulling in SQLAlchemy’s testing framework as well │ │ │ │ │ as the ORM into the module import space. This would only impact initial startup │ │ │ │ │ time and memory to a modest extent, however it’s best that these additional │ │ │ │ │ modules aren’t reverse-dependent on straight Core usage. │ │ │ │ │ References: _#_5_1_8_0 │ │ │ ├── ./usr/share/doc/python-sqlalchemy-doc/html/changelog/changelog_14.html │ │ │ │ @@ -1226,28 +1226,28 @@ │ │ │ │

      │ │ │ │
    • │ │ │ │
    │ │ │ │
│ │ │ │
│ │ │ │

sql

│ │ │ │
    │ │ │ │ -
  • [sql] [bug]

    Fixed caching issue where using the TextualSelect.add_cte() method │ │ │ │ -of the TextualSelect construct would not set a correct cache key │ │ │ │ -which distinguished between different CTE expressions.

    │ │ │ │ -

    References: #11471

    │ │ │ │ -

    │ │ │ │ -
  • │ │ │ │ -
  • [sql] [bug]

    Fixed caching issue where the │ │ │ │ +

  • [sql] [bug]

    Fixed caching issue where the │ │ │ │ Select.with_for_update.key_share element of │ │ │ │ Select.with_for_update() was not considered as part of the cache │ │ │ │ key, leading to incorrect caching if different variations of this parameter │ │ │ │ were used with an otherwise identical statement.

    │ │ │ │

    References: #11544

    │ │ │ │

    │ │ │ │
  • │ │ │ │ +
  • [sql] [bug]

    Fixed caching issue where using the TextualSelect.add_cte() method │ │ │ │ +of the TextualSelect construct would not set a correct cache key │ │ │ │ +which distinguished between different CTE expressions.

    │ │ │ │ +

    References: #11471

    │ │ │ │ +

    │ │ │ │ +
  • │ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │

mypy

│ │ │ │
    │ │ │ │
  • [mypy] [bug]

    The deprecated mypy plugin is no longer fully functional with the latest │ │ │ │ series of mypy 1.11.0, as changes in the mypy interpreter are no longer │ │ │ │ @@ -3065,36 +3065,36 @@ │ │ │ │ attributes and entities that are installed as part of an Insert, │ │ │ │ Update, or Delete construct. The │ │ │ │ Select.column_descriptions accessor is also now implemented for │ │ │ │ Core-only selectables.

    │ │ │ │

    References: #7861

    │ │ │ │

    │ │ │ │
  • │ │ │ │ -
  • [orm] [performance] [bug]

    Improvements in memory usage by the ORM, removing a significant set of │ │ │ │ -intermediary expression objects that are typically stored when a copy of an │ │ │ │ -expression object is created. These clones have been greatly reduced, │ │ │ │ -reducing the number of total expression objects stored in memory by │ │ │ │ -ORM mappings by about 30%.

    │ │ │ │ -

    References: #7823

    │ │ │ │ -

    │ │ │ │ -
  • │ │ │ │ -
  • [orm] [bug] [regression]

    Fixed regression in “dynamic” loader strategy where the │ │ │ │ +

  • [orm] [bug] [regression]

    Fixed regression in “dynamic” loader strategy where the │ │ │ │ Query.filter_by() method would not be given an appropriate │ │ │ │ entity to filter from, in the case where a “secondary” table were present │ │ │ │ in the relationship being queried and the mapping were against something │ │ │ │ complex such as a “with polymorphic”.

    │ │ │ │

    References: #7868

    │ │ │ │

    │ │ │ │
  • │ │ │ │ -
  • [orm] [bug]

    Fixed bug where composite() attributes would not work in │ │ │ │ +

  • [orm] [bug]

    Fixed bug where composite() attributes would not work in │ │ │ │ conjunction with the selectin_polymorphic() loader strategy for │ │ │ │ joined table inheritance.

    │ │ │ │

    References: #7801

    │ │ │ │

    │ │ │ │
  • │ │ │ │ +
  • [orm] [bug] [performance]

    Improvements in memory usage by the ORM, removing a significant set of │ │ │ │ +intermediary expression objects that are typically stored when a copy of an │ │ │ │ +expression object is created. These clones have been greatly reduced, │ │ │ │ +reducing the number of total expression objects stored in memory by │ │ │ │ +ORM mappings by about 30%.

    │ │ │ │ +

    References: #7823

    │ │ │ │ +

    │ │ │ │ +
  • │ │ │ │
  • [orm] [bug]

    Fixed issue where the selectin_polymorphic() loader option would │ │ │ │ not work with joined inheritance mappers that don’t have a fixed │ │ │ │ “polymorphic_on” column. Additionally added test support for a wider │ │ │ │ variety of usage patterns with this construct.

    │ │ │ │

    References: #7799

    │ │ │ │

    │ │ │ │
  • │ │ │ │ @@ -4821,15 +4821,15 @@ │ │ │ │

    │ │ │ │ │ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │

oracle

│ │ │ │
    │ │ │ │ -
  • [oracle] [performance] [bug]

    Added a CAST(VARCHAR2(128)) to the “table name”, “owner”, and other │ │ │ │ +

  • [oracle] [bug] [performance]

    Added a CAST(VARCHAR2(128)) to the “table name”, “owner”, and other │ │ │ │ DDL-name parameters as used in reflection queries against Oracle system │ │ │ │ views such as ALL_TABLES, ALL_TAB_CONSTRAINTS, etc to better enable │ │ │ │ indexing to take place against these columns, as they previously would be │ │ │ │ implicitly handled as NVARCHAR2 due to Python’s use of Unicode for strings; │ │ │ │ these columns are documented in all Oracle versions as being VARCHAR2 with │ │ │ │ lengths varying from 30 to 128 characters depending on server version. │ │ │ │ Additionally, test support has been enabled for Unicode-named DDL │ │ │ │ @@ -5544,24 +5544,15 @@ │ │ │ │

│ │ │ │
│ │ │ │
│ │ │ │

1.4.18

│ │ │ │ Released: June 10, 2021
│ │ │ │

orm

│ │ │ │
    │ │ │ │ -
  • [orm] [performance] [bug] [regression]

    Fixed regression involving how the ORM would resolve a given mapped column │ │ │ │ -to a result row, where under cases such as joined eager loading, a slightly │ │ │ │ -more expensive “fallback” could take place to set up this resolution due to │ │ │ │ -some logic that was removed since 1.3. The issue could also cause │ │ │ │ -deprecation warnings involving column resolution to be emitted when using a │ │ │ │ -1.4 style query with joined eager loading.

    │ │ │ │ -

    References: #6596

    │ │ │ │ -

    │ │ │ │ -
  • │ │ │ │ -
  • [orm] [bug]

    Clarified the current purpose of the │ │ │ │ +

  • [orm] [bug]

    Clarified the current purpose of the │ │ │ │ relationship.bake_queries flag, which in 1.4 is to enable │ │ │ │ or disable “lambda caching” of statements within the “lazyload” and │ │ │ │ “selectinload” loader strategies; this is separate from the more │ │ │ │ foundational SQL query cache that is used for most statements. │ │ │ │ Additionally, the lazy loader no longer uses its own cache for many-to-one │ │ │ │ SQL queries, which was an implementation quirk that doesn’t exist for any │ │ │ │ other loader scenario. Finally, the “lru cache” warning that the lazyloader │ │ │ │ @@ -5571,29 +5562,38 @@ │ │ │ │ setting bake_queries=False for such a relationship will remove this │ │ │ │ cache from being used, there’s no particular performance gain in this case │ │ │ │ as using no caching vs. using a cache that needs to refresh often likely │ │ │ │ still wins out on the caching being used side.

    │ │ │ │

    References: #6072, #6487

    │ │ │ │

    │ │ │ │
  • │ │ │ │ -
  • [orm] [bug] [regression]

    Adjusted the means by which classes such as scoped_session │ │ │ │ +

  • [orm] [bug] [regression]

    Adjusted the means by which classes such as scoped_session │ │ │ │ and AsyncSession are generated from the base │ │ │ │ Session class, such that custom Session │ │ │ │ subclasses such as that used by Flask-SQLAlchemy don’t need to implement │ │ │ │ positional arguments when they call into the superclass method, and can │ │ │ │ continue using the same argument styles as in previous releases.

    │ │ │ │

    References: #6285

    │ │ │ │

    │ │ │ │
  • │ │ │ │ -
  • [orm] [bug] [regression]

    Fixed issue where query production for joinedload against a complex left │ │ │ │ +

  • [orm] [bug] [regression]

    Fixed issue where query production for joinedload against a complex left │ │ │ │ hand side involving joined-table inheritance could fail to produce a │ │ │ │ correct query, due to a clause adaption issue.

    │ │ │ │

    References: #6595

    │ │ │ │

    │ │ │ │
  • │ │ │ │ +
  • [orm] [bug] [performance] [regression]

    Fixed regression involving how the ORM would resolve a given mapped column │ │ │ │ +to a result row, where under cases such as joined eager loading, a slightly │ │ │ │ +more expensive “fallback” could take place to set up this resolution due to │ │ │ │ +some logic that was removed since 1.3. The issue could also cause │ │ │ │ +deprecation warnings involving column resolution to be emitted when using a │ │ │ │ +1.4 style query with joined eager loading.

    │ │ │ │ +

    References: #6596

    │ │ │ │ +

    │ │ │ │ +
  • │ │ │ │
  • [orm] [bug]

    Fixed issue in experimental “select ORM objects from INSERT/UPDATE” use │ │ │ │ case where an error was raised if the statement were against a │ │ │ │ single-table-inheritance subclass.

    │ │ │ │

    References: #6591

    │ │ │ │

    │ │ │ │
  • │ │ │ │
  • [orm] [bug]

    The warning that’s emitted for relationship() when multiple │ │ │ │ @@ -6437,15 +6437,15 @@ │ │ │ │ synonyms can be established linking to these constructs which work │ │ │ │ fully. This is a behavior that was semi-explicitly disallowed previously, │ │ │ │ however since it did not fail in every scenario, explicit support │ │ │ │ for assoc proxy and hybrids has been added.

    │ │ │ │

    References: #6267

    │ │ │ │

    │ │ │ │
  • │ │ │ │ -
  • [orm] [performance] [bug] [regression] [sql]

    Fixed a critical performance issue where the traversal of a │ │ │ │ +

  • [orm] [bug] [performance] [regression] [sql]

    Fixed a critical performance issue where the traversal of a │ │ │ │ select() construct would traverse a repetitive product of the │ │ │ │ represented FROM clauses as they were each referenced by columns in │ │ │ │ the columns clause; for a series of nested subqueries with lots of columns │ │ │ │ this could cause a large delay and significant memory growth. This │ │ │ │ traversal is used by a wide variety of SQL and ORM functions, including by │ │ │ │ the ORM Session when it’s configured to have │ │ │ │ “table-per-bind”, which while this is not a common use case, it seems to be │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -808,24 +808,24 @@ │ │ │ │ │ sqlalchemy.util.await_only() directly. │ │ │ │ │ [[eennggiinnee]] [[bbuugg]] _¶ │ │ │ │ │ Adjustments to the C extensions, which are specific to the SQLAlchemy 1.x │ │ │ │ │ series, to work under Python 3.13. Pull request courtesy Ben Beasley. │ │ │ │ │ References: _#_1_1_4_9_9 │ │ │ │ │ ******** ssqqll_?¶ ******** │ │ │ │ │ * [[ssqqll]] [[bbuugg]] _¶ │ │ │ │ │ - Fixed caching issue where using the _T_e_x_t_u_a_l_S_e_l_e_c_t_._a_d_d___c_t_e_(_) method of the │ │ │ │ │ - _T_e_x_t_u_a_l_S_e_l_e_c_t construct would not set a correct cache key which │ │ │ │ │ - distinguished between different CTE expressions. │ │ │ │ │ - References: _#_1_1_4_7_1 │ │ │ │ │ -[[ssqqll]] [[bbuugg]] _¶ │ │ │ │ │ -Fixed caching issue where the _S_e_l_e_c_t_._w_i_t_h___f_o_r___u_p_d_a_t_e_._k_e_y___s_h_a_r_e element of │ │ │ │ │ -_S_e_l_e_c_t_._w_i_t_h___f_o_r___u_p_d_a_t_e_(_) was not considered as part of the cache key, leading │ │ │ │ │ -to incorrect caching if different variations of this parameter were used with │ │ │ │ │ -an otherwise identical statement. │ │ │ │ │ -References: _#_1_1_5_4_4 │ │ │ │ │ + Fixed caching issue where the _S_e_l_e_c_t_._w_i_t_h___f_o_r___u_p_d_a_t_e_._k_e_y___s_h_a_r_e element of │ │ │ │ │ + _S_e_l_e_c_t_._w_i_t_h___f_o_r___u_p_d_a_t_e_(_) was not considered as part of the cache key, │ │ │ │ │ + leading to incorrect caching if different variations of this parameter │ │ │ │ │ + were used with an otherwise identical statement. │ │ │ │ │ + References: _#_1_1_5_4_4 │ │ │ │ │ +[[ssqqll]] [[bbuugg]] _¶ │ │ │ │ │ +Fixed caching issue where using the _T_e_x_t_u_a_l_S_e_l_e_c_t_._a_d_d___c_t_e_(_) method of the │ │ │ │ │ +_T_e_x_t_u_a_l_S_e_l_e_c_t construct would not set a correct cache key which distinguished │ │ │ │ │ +between different CTE expressions. │ │ │ │ │ +References: _#_1_1_4_7_1 │ │ │ │ │ ******** mmyyppyy_?¶ ******** │ │ │ │ │ * [[mmyyppyy]] [[bbuugg]] _¶ │ │ │ │ │ The deprecated mypy plugin is no longer fully functional with the latest │ │ │ │ │ series of mypy 1.11.0, as changes in the mypy interpreter are no longer │ │ │ │ │ compatible with the approach used by the plugin. If code is dependent on │ │ │ │ │ the mypy plugin with sqlalchemy2-stubs, it’s recommended to pin mypy to │ │ │ │ │ be below the 1.11.0 series. Seek upgrading to the 2.0 series of │ │ │ │ │ @@ -2032,31 +2032,31 @@ │ │ │ │ │ [[oorrmm]] [[uusseeccaassee]] _¶ │ │ │ │ │ Added new attributes _U_p_d_a_t_e_B_a_s_e_._r_e_t_u_r_n_i_n_g___c_o_l_u_m_n___d_e_s_c_r_i_p_t_i_o_n_s and │ │ │ │ │ _U_p_d_a_t_e_B_a_s_e_._e_n_t_i_t_y___d_e_s_c_r_i_p_t_i_o_n to allow for inspection of ORM attributes and │ │ │ │ │ entities that are installed as part of an _I_n_s_e_r_t, _U_p_d_a_t_e, or _D_e_l_e_t_e construct. │ │ │ │ │ The _S_e_l_e_c_t_._c_o_l_u_m_n___d_e_s_c_r_i_p_t_i_o_n_s accessor is also now implemented for Core-only │ │ │ │ │ selectables. │ │ │ │ │ References: _#_7_8_6_1 │ │ │ │ │ -[[oorrmm]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] _¶ │ │ │ │ │ -Improvements in memory usage by the ORM, removing a significant set of │ │ │ │ │ -intermediary expression objects that are typically stored when a copy of an │ │ │ │ │ -expression object is created. These clones have been greatly reduced, reducing │ │ │ │ │ -the number of total expression objects stored in memory by ORM mappings by │ │ │ │ │ -about 30%. │ │ │ │ │ -References: _#_7_8_2_3 │ │ │ │ │ [[oorrmm]] [[bbuugg]] [[rreeggrreessssiioonn]] _¶ │ │ │ │ │ Fixed regression in “dynamic” loader strategy where the _Q_u_e_r_y_._f_i_l_t_e_r___b_y_(_) │ │ │ │ │ method would not be given an appropriate entity to filter from, in the case │ │ │ │ │ where a “secondary” table were present in the relationship being queried and │ │ │ │ │ the mapping were against something complex such as a “with polymorphic”. │ │ │ │ │ References: _#_7_8_6_8 │ │ │ │ │ [[oorrmm]] [[bbuugg]] _¶ │ │ │ │ │ Fixed bug where _c_o_m_p_o_s_i_t_e_(_) attributes would not work in conjunction with the │ │ │ │ │ _s_e_l_e_c_t_i_n___p_o_l_y_m_o_r_p_h_i_c_(_) loader strategy for joined table inheritance. │ │ │ │ │ References: _#_7_8_0_1 │ │ │ │ │ +[[oorrmm]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] _¶ │ │ │ │ │ +Improvements in memory usage by the ORM, removing a significant set of │ │ │ │ │ +intermediary expression objects that are typically stored when a copy of an │ │ │ │ │ +expression object is created. These clones have been greatly reduced, reducing │ │ │ │ │ +the number of total expression objects stored in memory by ORM mappings by │ │ │ │ │ +about 30%. │ │ │ │ │ +References: _#_7_8_2_3 │ │ │ │ │ [[oorrmm]] [[bbuugg]] _¶ │ │ │ │ │ Fixed issue where the _s_e_l_e_c_t_i_n___p_o_l_y_m_o_r_p_h_i_c_(_) loader option would not work with │ │ │ │ │ joined inheritance mappers that don’t have a fixed “polymorphic_on” column. │ │ │ │ │ Additionally added test support for a wider variety of usage patterns with this │ │ │ │ │ construct. │ │ │ │ │ References: _#_7_7_9_9 │ │ │ │ │ [[oorrmm]] [[bbuugg]] _¶ │ │ │ │ │ @@ -3255,15 +3255,15 @@ │ │ │ │ │ * [[mmssssqqll]] [[bbuugg]] [[rreefflleeccttiioonn]] _¶ │ │ │ │ │ Fixed an issue where sqlalchemy.engine.reflection.has_table() returned │ │ │ │ │ True for local temporary tables that actually belonged to a different SQL │ │ │ │ │ Server session (connection). An extra check is now performed to ensure │ │ │ │ │ that the temp table detected is in fact owned by the current session. │ │ │ │ │ References: _#_6_9_1_0 │ │ │ │ │ ******** oorraaccllee_?¶ ******** │ │ │ │ │ - * [[oorraaccllee]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] _¶ │ │ │ │ │ + * [[oorraaccllee]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] _¶ │ │ │ │ │ Added a CAST(VARCHAR2(128)) to the “table name”, “owner”, and other DDL- │ │ │ │ │ name parameters as used in reflection queries against Oracle system views │ │ │ │ │ such as ALL_TABLES, ALL_TAB_CONSTRAINTS, etc to better enable indexing to │ │ │ │ │ take place against these columns, as they previously would be implicitly │ │ │ │ │ handled as NVARCHAR2 due to Python’s use of Unicode for strings; these │ │ │ │ │ columns are documented in all Oracle versions as being VARCHAR2 with │ │ │ │ │ lengths varying from 30 to 128 characters depending on server version. │ │ │ │ │ @@ -3763,50 +3763,51 @@ │ │ │ │ │ the INSERT thus triggering SQLAlchemy’s feature of setting IDENTITY INSERT to │ │ │ │ │ “on”; it’s in this directive where the schema translate map would fail to be │ │ │ │ │ honored. │ │ │ │ │ References: _#_6_6_5_8 │ │ │ │ │ ********** 11..44..1188_?¶ ********** │ │ │ │ │ Released: June 10, 2021 │ │ │ │ │ ******** oorrmm_?¶ ******** │ │ │ │ │ - * [[oorrmm]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] [[rreeggrreessssiioonn]] _¶ │ │ │ │ │ - Fixed regression involving how the ORM would resolve a given mapped │ │ │ │ │ - column to a result row, where under cases such as joined eager loading, a │ │ │ │ │ - slightly more expensive “fallback” could take place to set up this │ │ │ │ │ - resolution due to some logic that was removed since 1.3. The issue could │ │ │ │ │ - also cause deprecation warnings involving column resolution to be emitted │ │ │ │ │ - when using a 1.4 style query with joined eager loading. │ │ │ │ │ - References: _#_6_5_9_6 │ │ │ │ │ -[[oorrmm]] [[bbuugg]] _¶ │ │ │ │ │ -Clarified the current purpose of the _r_e_l_a_t_i_o_n_s_h_i_p_._b_a_k_e___q_u_e_r_i_e_s flag, which in │ │ │ │ │ -1.4 is to enable or disable “lambda caching” of statements within the │ │ │ │ │ -“lazyload” and “selectinload” loader strategies; this is separate from the more │ │ │ │ │ -foundational SQL query cache that is used for most statements. Additionally, │ │ │ │ │ -the lazy loader no longer uses its own cache for many-to-one SQL queries, which │ │ │ │ │ -was an implementation quirk that doesn’t exist for any other loader scenario. │ │ │ │ │ -Finally, the “lru cache” warning that the lazyloader and selectinloader │ │ │ │ │ -strategies could emit when handling a wide array of class/relationship │ │ │ │ │ -combinations has been removed; based on analysis of some end-user cases, this │ │ │ │ │ -warning doesn’t suggest any significant issue. While setting bake_queries=False │ │ │ │ │ -for such a relationship will remove this cache from being used, there’s no │ │ │ │ │ -particular performance gain in this case as using no caching vs. using a cache │ │ │ │ │ -that needs to refresh often likely still wins out on the caching being used │ │ │ │ │ -side. │ │ │ │ │ -References: _#_6_0_7_2, _#_6_4_8_7 │ │ │ │ │ + * [[oorrmm]] [[bbuugg]] _¶ │ │ │ │ │ + Clarified the current purpose of the _r_e_l_a_t_i_o_n_s_h_i_p_._b_a_k_e___q_u_e_r_i_e_s flag, │ │ │ │ │ + which in 1.4 is to enable or disable “lambda caching” of statements │ │ │ │ │ + within the “lazyload” and “selectinload” loader strategies; this is │ │ │ │ │ + separate from the more foundational SQL query cache that is used for most │ │ │ │ │ + statements. Additionally, the lazy loader no longer uses its own cache │ │ │ │ │ + for many-to-one SQL queries, which was an implementation quirk that │ │ │ │ │ + doesn’t exist for any other loader scenario. Finally, the “lru cache” │ │ │ │ │ + warning that the lazyloader and selectinloader strategies could emit when │ │ │ │ │ + handling a wide array of class/relationship combinations has been │ │ │ │ │ + removed; based on analysis of some end-user cases, this warning doesn’t │ │ │ │ │ + suggest any significant issue. While setting bake_queries=False for such │ │ │ │ │ + a relationship will remove this cache from being used, there’s no │ │ │ │ │ + particular performance gain in this case as using no caching vs. using a │ │ │ │ │ + cache that needs to refresh often likely still wins out on the caching │ │ │ │ │ + being used side. │ │ │ │ │ + References: _#_6_0_7_2, _#_6_4_8_7 │ │ │ │ │ [[oorrmm]] [[bbuugg]] [[rreeggrreessssiioonn]] _¶ │ │ │ │ │ Adjusted the means by which classes such as _s_c_o_p_e_d___s_e_s_s_i_o_n and _A_s_y_n_c_S_e_s_s_i_o_n are │ │ │ │ │ generated from the base _S_e_s_s_i_o_n class, such that custom _S_e_s_s_i_o_n subclasses such │ │ │ │ │ as that used by Flask-SQLAlchemy don’t need to implement positional arguments │ │ │ │ │ when they call into the superclass method, and can continue using the same │ │ │ │ │ argument styles as in previous releases. │ │ │ │ │ References: _#_6_2_8_5 │ │ │ │ │ [[oorrmm]] [[bbuugg]] [[rreeggrreessssiioonn]] _¶ │ │ │ │ │ Fixed issue where query production for joinedload against a complex left hand │ │ │ │ │ side involving joined-table inheritance could fail to produce a correct query, │ │ │ │ │ due to a clause adaption issue. │ │ │ │ │ References: _#_6_5_9_5 │ │ │ │ │ +[[oorrmm]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] [[rreeggrreessssiioonn]] _¶ │ │ │ │ │ +Fixed regression involving how the ORM would resolve a given mapped column to a │ │ │ │ │ +result row, where under cases such as joined eager loading, a slightly more │ │ │ │ │ +expensive “fallback” could take place to set up this resolution due to some │ │ │ │ │ +logic that was removed since 1.3. The issue could also cause deprecation │ │ │ │ │ +warnings involving column resolution to be emitted when using a 1.4 style query │ │ │ │ │ +with joined eager loading. │ │ │ │ │ +References: _#_6_5_9_6 │ │ │ │ │ [[oorrmm]] [[bbuugg]] _¶ │ │ │ │ │ Fixed issue in experimental “select ORM objects from INSERT/UPDATE” use case │ │ │ │ │ where an error was raised if the statement were against a single-table- │ │ │ │ │ inheritance subclass. │ │ │ │ │ References: _#_6_5_9_1 │ │ │ │ │ [[oorrmm]] [[bbuugg]] _¶ │ │ │ │ │ The warning that’s emitted for _r_e_l_a_t_i_o_n_s_h_i_p_(_) when multiple relationships would │ │ │ │ │ @@ -4376,15 +4377,15 @@ │ │ │ │ │ Established support for synoynm() in conjunction with hybrid property, │ │ │ │ │ assocaitionproxy is set up completely, including that synonyms can be │ │ │ │ │ established linking to these constructs which work fully. This is a │ │ │ │ │ behavior that was semi-explicitly disallowed previously, however since it │ │ │ │ │ did not fail in every scenario, explicit support for assoc proxy and │ │ │ │ │ hybrids has been added. │ │ │ │ │ References: _#_6_2_6_7 │ │ │ │ │ -[[oorrmm]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] [[rreeggrreessssiioonn]] [[ssqqll]] _¶ │ │ │ │ │ +[[oorrmm]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] [[rreeggrreessssiioonn]] [[ssqqll]] _¶ │ │ │ │ │ Fixed a critical performance issue where the traversal of a _s_e_l_e_c_t_(_) construct │ │ │ │ │ would traverse a repetitive product of the represented FROM clauses as they │ │ │ │ │ were each referenced by columns in the columns clause; for a series of nested │ │ │ │ │ subqueries with lots of columns this could cause a large delay and significant │ │ │ │ │ memory growth. This traversal is used by a wide variety of SQL and ORM │ │ │ │ │ functions, including by the ORM _S_e_s_s_i_o_n when it’s configured to have “table- │ │ │ │ │ per-bind”, which while this is not a common use case, it seems to be what │ │ │ ├── ./usr/share/doc/python-sqlalchemy-doc/html/changelog/changelog_20.html │ │ │ │ @@ -1573,32 +1573,32 @@ │ │ │ │

│ │ │ │
│ │ │ │
│ │ │ │

2.0.28

│ │ │ │ Released: March 4, 2024
│ │ │ │

orm

│ │ │ │
    │ │ │ │ -
  • [orm] [performance] [bug] [regression]

    Adjusted the fix made in #10570, released in 2.0.23, where new │ │ │ │ +

  • [orm] [bug] [regression]

    Fixed regression caused by #9779 where using the “secondary” table │ │ │ │ +in a relationship and_() expression would fail to be aliased to match │ │ │ │ +how the “secondary” table normally renders within a │ │ │ │ +Select.join() expression, leading to an invalid query.

    │ │ │ │ +

    References: #11010

    │ │ │ │ +

    │ │ │ │ +
  • │ │ │ │ +
  • [orm] [bug] [performance] [regression]

    Adjusted the fix made in #10570, released in 2.0.23, where new │ │ │ │ logic was added to reconcile possibly changing bound parameter values │ │ │ │ across cache key generations used within the with_expression() │ │ │ │ construct. The new logic changes the approach by which the new bound │ │ │ │ parameter values are associated with the statement, avoiding the need to │ │ │ │ deep-copy the statement which can result in a significant performance │ │ │ │ penalty for very deep / complex SQL constructs. The new approach no longer │ │ │ │ requires this deep-copy step.

    │ │ │ │

    References: #11085

    │ │ │ │

    │ │ │ │
  • │ │ │ │ -
  • [orm] [bug] [regression]

    Fixed regression caused by #9779 where using the “secondary” table │ │ │ │ -in a relationship and_() expression would fail to be aliased to match │ │ │ │ -how the “secondary” table normally renders within a │ │ │ │ -Select.join() expression, leading to an invalid query.

    │ │ │ │ -

    References: #11010

    │ │ │ │ -

    │ │ │ │ -
  • │ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │

engine

│ │ │ │ │ │ │ │
│ │ │ │
│ │ │ │

oracle

│ │ │ │
    │ │ │ │ -
  • [oracle] [performance] [bug]

    Changed the default arraysize of the Oracle dialects so that the value set │ │ │ │ +

  • [oracle] [bug] [performance]

    Changed the default arraysize of the Oracle dialects so that the value set │ │ │ │ by the driver is used, that is 100 at the time of writing for both │ │ │ │ cx_oracle and oracledb. Previously the value was set to 50 by default. The │ │ │ │ setting of 50 could cause significant performance regressions compared to │ │ │ │ when using cx_oracle/oracledb alone to fetch many hundreds of rows over │ │ │ │ slower networks.

    │ │ │ │

    References: #10877

    │ │ │ │

    │ │ │ │ @@ -6073,39 +6073,39 @@ │ │ │ │ relationship() etc. to provide for the Python dataclasses │ │ │ │ compare parameter on field(), when using the │ │ │ │ Declarative Dataclass Mapping feature. Pull request courtesy │ │ │ │ Simon Schiele.

    │ │ │ │

    References: #8905

    │ │ │ │

    │ │ │ │
  • │ │ │ │ -
  • [orm] [performance] [bug]

    Additional performance enhancements within ORM-enabled SQL statements, │ │ │ │ -specifically targeting callcounts within the construction of ORM │ │ │ │ -statements, using combinations of aliased() with │ │ │ │ -union() and similar “compound” constructs, in addition to direct │ │ │ │ -performance improvements to the corresponding_column() internal method │ │ │ │ -that is used heavily by the ORM by constructs like aliased() and │ │ │ │ -similar.

    │ │ │ │ -

    References: #8796

    │ │ │ │ -

    │ │ │ │ -
  • │ │ │ │ -
  • [orm] [bug]

    Fixed issue where use of an unknown datatype within a Mapped │ │ │ │ +

  • [orm] [bug]

    Fixed issue where use of an unknown datatype within a Mapped │ │ │ │ annotation for a column-based attribute would silently fail to map the │ │ │ │ attribute, rather than reporting an exception; an informative exception │ │ │ │ message is now raised.

    │ │ │ │

    References: #8888

    │ │ │ │

    │ │ │ │
  • │ │ │ │ -
  • [orm] [bug]

    Fixed a suite of issues involving Mapped use with dictionary │ │ │ │ +

  • [orm] [bug]

    Fixed a suite of issues involving Mapped use with dictionary │ │ │ │ types, such as Mapped[Dict[str, str] | None], would not be correctly │ │ │ │ interpreted in Declarative ORM mappings. Support to correctly │ │ │ │ “de-optionalize” this type including for lookup in type_annotation_map │ │ │ │ has been fixed.

    │ │ │ │

    References: #8777

    │ │ │ │

    │ │ │ │
  • │ │ │ │ +
  • [orm] [bug] [performance]

    Additional performance enhancements within ORM-enabled SQL statements, │ │ │ │ +specifically targeting callcounts within the construction of ORM │ │ │ │ +statements, using combinations of aliased() with │ │ │ │ +union() and similar “compound” constructs, in addition to direct │ │ │ │ +performance improvements to the corresponding_column() internal method │ │ │ │ +that is used heavily by the ORM by constructs like aliased() and │ │ │ │ +similar.

    │ │ │ │ +

    References: #8796

    │ │ │ │ +

    │ │ │ │ +
  • │ │ │ │
  • [orm] [bug]

    Fixed bug in Declarative Dataclass Mapping feature where using │ │ │ │ plain dataclass fields with the __allow_unmapped__ directive in a │ │ │ │ mapping would not create a dataclass with the correct class-level state for │ │ │ │ those fields, copying the raw Field object to the class inappropriately │ │ │ │ after dataclasses itself had replaced the Field object with the │ │ │ │ class-level default value.

    │ │ │ │

    References: #8880

    │ │ │ │ @@ -7952,29 +7952,15 @@ │ │ │ │ that may refer to additional tables within the WHERE criteria of the │ │ │ │ statement without the need to use subqueries. This syntax is invoked │ │ │ │ automatically when using the Update construct when more than │ │ │ │ one table or other entity or selectable is used.

    │ │ │ │

    References: #7185

    │ │ │ │

    │ │ │ │
  • │ │ │ │ -
  • [sqlite] [performance] [bug]

    The SQLite dialect now defaults to QueuePool when a file │ │ │ │ -based database is used. This is set along with setting the │ │ │ │ -check_same_thread parameter to False. It has been observed that the │ │ │ │ -previous approach of defaulting to NullPool, which does not │ │ │ │ -hold onto database connections after they are released, did in fact have a │ │ │ │ -measurable negative performance impact. As always, the pool class is │ │ │ │ -customizable via the create_engine.poolclass parameter.

    │ │ │ │ -
    │ │ │ │ -

    See also

    │ │ │ │ -

    The SQLite dialect uses QueuePool for file-based databases

    │ │ │ │ -
    │ │ │ │ -

    References: #7490

    │ │ │ │ -

    │ │ │ │ -
  • │ │ │ │ -
  • [sqlite] [bug]

    Removed the warning that emits from the Numeric type about │ │ │ │ +

  • [sqlite] [bug]

    Removed the warning that emits from the Numeric type about │ │ │ │ DBAPIs not supporting Decimal values natively. This warning was oriented │ │ │ │ towards SQLite, which does not have any real way without additional │ │ │ │ extensions or workarounds of handling precision numeric values more than 15 │ │ │ │ significant digits as it only uses floating point math to represent │ │ │ │ numbers. As this is a known and documented limitation in SQLite itself, and │ │ │ │ not a quirk of the pysqlite driver, there’s no need for SQLAlchemy to warn │ │ │ │ for this. The change does not otherwise modify how precision numerics are │ │ │ │ @@ -7982,14 +7968,28 @@ │ │ │ │ as configured with the Numeric, Float , and │ │ │ │ related datatypes, just without the ability to maintain precision beyond 15 │ │ │ │ significant digits when using SQLite, unless alternate representations such │ │ │ │ as strings are used.

    │ │ │ │

    References: #7299

    │ │ │ │

    │ │ │ │
  • │ │ │ │ +
  • [sqlite] [bug] [performance]

    The SQLite dialect now defaults to QueuePool when a file │ │ │ │ +based database is used. This is set along with setting the │ │ │ │ +check_same_thread parameter to False. It has been observed that the │ │ │ │ +previous approach of defaulting to NullPool, which does not │ │ │ │ +hold onto database connections after they are released, did in fact have a │ │ │ │ +measurable negative performance impact. As always, the pool class is │ │ │ │ +customizable via the create_engine.poolclass parameter.

    │ │ │ │ +
    │ │ │ │ +

    See also

    │ │ │ │ +

    The SQLite dialect uses QueuePool for file-based databases

    │ │ │ │ +
    │ │ │ │ +

    References: #7490

    │ │ │ │ +

    │ │ │ │ +
  • │ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │

mssql

│ │ │ │
    │ │ │ │
  • [mssql] [usecase]

    Implemented reflection of the “clustered index” flag mssql_clustered │ │ │ │ for the SQL Server dialect. Pull request courtesy John Lennox.

    │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -1021,30 +1021,29 @@ │ │ │ │ │ should hopefully prevent issues with large suite runs on CPU loaded │ │ │ │ │ hardware where the event loop seems to become corrupted, leading to │ │ │ │ │ cascading failures. │ │ │ │ │ References: _#_1_1_1_8_7 │ │ │ │ │ ********** 22..00..2288_?¶ ********** │ │ │ │ │ Released: March 4, 2024 │ │ │ │ │ ******** oorrmm_?¶ ******** │ │ │ │ │ - * [[oorrmm]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] [[rreeggrreessssiioonn]] _¶ │ │ │ │ │ - Adjusted the fix made in _#_1_0_5_7_0, released in 2.0.23, where new logic was │ │ │ │ │ - added to reconcile possibly changing bound parameter values across cache │ │ │ │ │ - key generations used within the _w_i_t_h___e_x_p_r_e_s_s_i_o_n_(_) construct. The new │ │ │ │ │ - logic changes the approach by which the new bound parameter values are │ │ │ │ │ - associated with the statement, avoiding the need to deep-copy the │ │ │ │ │ - statement which can result in a significant performance penalty for very │ │ │ │ │ - deep / complex SQL constructs. The new approach no longer requires this │ │ │ │ │ - deep-copy step. │ │ │ │ │ - References: _#_1_1_0_8_5 │ │ │ │ │ -[[oorrmm]] [[bbuugg]] [[rreeggrreessssiioonn]] _¶ │ │ │ │ │ -Fixed regression caused by _#_9_7_7_9 where using the “secondary” table in a │ │ │ │ │ -relationship and_() expression would fail to be aliased to match how the │ │ │ │ │ -“secondary” table normally renders within a _S_e_l_e_c_t_._j_o_i_n_(_) expression, leading │ │ │ │ │ -to an invalid query. │ │ │ │ │ -References: _#_1_1_0_1_0 │ │ │ │ │ + * [[oorrmm]] [[bbuugg]] [[rreeggrreessssiioonn]] _¶ │ │ │ │ │ + Fixed regression caused by _#_9_7_7_9 where using the “secondary” table in a │ │ │ │ │ + relationship and_() expression would fail to be aliased to match how the │ │ │ │ │ + “secondary” table normally renders within a _S_e_l_e_c_t_._j_o_i_n_(_) expression, │ │ │ │ │ + leading to an invalid query. │ │ │ │ │ + References: _#_1_1_0_1_0 │ │ │ │ │ +[[oorrmm]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] [[rreeggrreessssiioonn]] _¶ │ │ │ │ │ +Adjusted the fix made in _#_1_0_5_7_0, released in 2.0.23, where new logic was added │ │ │ │ │ +to reconcile possibly changing bound parameter values across cache key │ │ │ │ │ +generations used within the _w_i_t_h___e_x_p_r_e_s_s_i_o_n_(_) construct. The new logic changes │ │ │ │ │ +the approach by which the new bound parameter values are associated with the │ │ │ │ │ +statement, avoiding the need to deep-copy the statement which can result in a │ │ │ │ │ +significant performance penalty for very deep / complex SQL constructs. The new │ │ │ │ │ +approach no longer requires this deep-copy step. │ │ │ │ │ +References: _#_1_1_0_8_5 │ │ │ │ │ ******** eennggiinnee_?¶ ******** │ │ │ │ │ * [[eennggiinnee]] [[uusseeccaassee]] _¶ │ │ │ │ │ Added new core execution option │ │ │ │ │ _C_o_n_n_e_c_t_i_o_n_._e_x_e_c_u_t_i_o_n___o_p_t_i_o_n_s_._p_r_e_s_e_r_v_e___r_o_w_c_o_u_n_t. When set, the │ │ │ │ │ cursor.rowcount attribute from the DBAPI cursor will be unconditionally │ │ │ │ │ memoized at statement execution time, so that whatever value the DBAPI │ │ │ │ │ offers for any kind of statement will be available using the │ │ │ │ │ @@ -1191,15 +1190,15 @@ │ │ │ │ │ Fixed an issue regarding the use of the _U_u_i_d datatype with the │ │ │ │ │ _U_u_i_d_._a_s___u_u_i_d parameter set to False, when using the pymssql dialect. ORM- │ │ │ │ │ optimized INSERT statements (e.g. the “insertmanyvalues” feature) would │ │ │ │ │ not correctly align primary key UUID values for bulk INSERT statements, │ │ │ │ │ resulting in errors. Similar issues were fixed for the PostgreSQL drivers │ │ │ │ │ as well. │ │ │ │ │ ******** oorraaccllee_?¶ ******** │ │ │ │ │ - * [[oorraaccllee]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] _¶ │ │ │ │ │ + * [[oorraaccllee]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] _¶ │ │ │ │ │ Changed the default arraysize of the Oracle dialects so that the value │ │ │ │ │ set by the driver is used, that is 100 at the time of writing for both │ │ │ │ │ cx_oracle and oracledb. Previously the value was set to 50 by default. │ │ │ │ │ The setting of 50 could cause significant performance regressions │ │ │ │ │ compared to when using cx_oracle/oracledb alone to fetch many hundreds of │ │ │ │ │ rows over slower networks. │ │ │ │ │ References: _#_1_0_8_7_7 │ │ │ │ │ @@ -4086,33 +4085,33 @@ │ │ │ │ │ References: _#_8_8_5_9 │ │ │ │ │ [[oorrmm]] [[uusseeccaassee]] _¶ │ │ │ │ │ Added _m_a_p_p_e_d___c_o_l_u_m_n_._c_o_m_p_a_r_e parameter to relevant ORM attribute constructs │ │ │ │ │ including _m_a_p_p_e_d___c_o_l_u_m_n_(_), _r_e_l_a_t_i_o_n_s_h_i_p_(_) etc. to provide for the Python │ │ │ │ │ dataclasses compare parameter on field(), when using the _D_e_c_l_a_r_a_t_i_v_e_ _D_a_t_a_c_l_a_s_s │ │ │ │ │ _M_a_p_p_i_n_g feature. Pull request courtesy Simon Schiele. │ │ │ │ │ References: _#_8_9_0_5 │ │ │ │ │ -[[oorrmm]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] _¶ │ │ │ │ │ -Additional performance enhancements within ORM-enabled SQL statements, │ │ │ │ │ -specifically targeting callcounts within the construction of ORM statements, │ │ │ │ │ -using combinations of _a_l_i_a_s_e_d_(_) with _u_n_i_o_n_(_) and similar “compound” constructs, │ │ │ │ │ -in addition to direct performance improvements to the corresponding_column() │ │ │ │ │ -internal method that is used heavily by the ORM by constructs like _a_l_i_a_s_e_d_(_) │ │ │ │ │ -and similar. │ │ │ │ │ -References: _#_8_7_9_6 │ │ │ │ │ [[oorrmm]] [[bbuugg]] _¶ │ │ │ │ │ Fixed issue where use of an unknown datatype within a _M_a_p_p_e_d annotation for a │ │ │ │ │ column-based attribute would silently fail to map the attribute, rather than │ │ │ │ │ reporting an exception; an informative exception message is now raised. │ │ │ │ │ References: _#_8_8_8_8 │ │ │ │ │ [[oorrmm]] [[bbuugg]] _¶ │ │ │ │ │ Fixed a suite of issues involving _M_a_p_p_e_d use with dictionary types, such as │ │ │ │ │ Mapped[Dict[str, str] | None], would not be correctly interpreted in │ │ │ │ │ Declarative ORM mappings. Support to correctly “de-optionalize” this type │ │ │ │ │ including for lookup in type_annotation_map has been fixed. │ │ │ │ │ References: _#_8_7_7_7 │ │ │ │ │ +[[oorrmm]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] _¶ │ │ │ │ │ +Additional performance enhancements within ORM-enabled SQL statements, │ │ │ │ │ +specifically targeting callcounts within the construction of ORM statements, │ │ │ │ │ +using combinations of _a_l_i_a_s_e_d_(_) with _u_n_i_o_n_(_) and similar “compound” constructs, │ │ │ │ │ +in addition to direct performance improvements to the corresponding_column() │ │ │ │ │ +internal method that is used heavily by the ORM by constructs like _a_l_i_a_s_e_d_(_) │ │ │ │ │ +and similar. │ │ │ │ │ +References: _#_8_7_9_6 │ │ │ │ │ [[oorrmm]] [[bbuugg]] _¶ │ │ │ │ │ Fixed bug in _D_e_c_l_a_r_a_t_i_v_e_ _D_a_t_a_c_l_a_s_s_ _M_a_p_p_i_n_g feature where using plain dataclass │ │ │ │ │ fields with the __allow_unmapped__ directive in a mapping would not create a │ │ │ │ │ dataclass with the correct class-level state for those fields, copying the raw │ │ │ │ │ Field object to the class inappropriately after dataclasses itself had replaced │ │ │ │ │ the Field object with the class-level default value. │ │ │ │ │ References: _#_8_8_8_0 │ │ │ │ │ @@ -5487,38 +5486,38 @@ │ │ │ │ │ [[ssqqlliittee]] [[uusseeccaassee]] _¶ │ │ │ │ │ The SQLite dialect now supports UPDATE..FROM syntax, for UPDATE statements that │ │ │ │ │ may refer to additional tables within the WHERE criteria of the statement │ │ │ │ │ without the need to use subqueries. This syntax is invoked automatically when │ │ │ │ │ using the _U_p_d_a_t_e construct when more than one table or other entity or │ │ │ │ │ selectable is used. │ │ │ │ │ References: _#_7_1_8_5 │ │ │ │ │ -[[ssqqlliittee]] [[ppeerrffoorrmmaannccee]] [[bbuugg]] _¶ │ │ │ │ │ -The SQLite dialect now defaults to _Q_u_e_u_e_P_o_o_l when a file based database is │ │ │ │ │ -used. This is set along with setting the check_same_thread parameter to False. │ │ │ │ │ -It has been observed that the previous approach of defaulting to _N_u_l_l_P_o_o_l, │ │ │ │ │ -which does not hold onto database connections after they are released, did in │ │ │ │ │ -fact have a measurable negative performance impact. As always, the pool class │ │ │ │ │ -is customizable via the _c_r_e_a_t_e___e_n_g_i_n_e_._p_o_o_l_c_l_a_s_s parameter. │ │ │ │ │ -See also │ │ │ │ │ -_T_h_e_ _S_Q_L_i_t_e_ _d_i_a_l_e_c_t_ _u_s_e_s_ _Q_u_e_u_e_P_o_o_l_ _f_o_r_ _f_i_l_e_-_b_a_s_e_d_ _d_a_t_a_b_a_s_e_s │ │ │ │ │ -References: _#_7_4_9_0 │ │ │ │ │ [[ssqqlliittee]] [[bbuugg]] _¶ │ │ │ │ │ Removed the warning that emits from the _N_u_m_e_r_i_c type about DBAPIs not │ │ │ │ │ supporting Decimal values natively. This warning was oriented towards SQLite, │ │ │ │ │ which does not have any real way without additional extensions or workarounds │ │ │ │ │ of handling precision numeric values more than 15 significant digits as it only │ │ │ │ │ uses floating point math to represent numbers. As this is a known and │ │ │ │ │ documented limitation in SQLite itself, and not a quirk of the pysqlite driver, │ │ │ │ │ there’s no need for SQLAlchemy to warn for this. The change does not otherwise │ │ │ │ │ modify how precision numerics are handled. Values can continue to be handled as │ │ │ │ │ Decimal() or float() as configured with the _N_u_m_e_r_i_c, _F_l_o_a_t , and related │ │ │ │ │ datatypes, just without the ability to maintain precision beyond 15 significant │ │ │ │ │ digits when using SQLite, unless alternate representations such as strings are │ │ │ │ │ used. │ │ │ │ │ References: _#_7_2_9_9 │ │ │ │ │ +[[ssqqlliittee]] [[bbuugg]] [[ppeerrffoorrmmaannccee]] _¶ │ │ │ │ │ +The SQLite dialect now defaults to _Q_u_e_u_e_P_o_o_l when a file based database is │ │ │ │ │ +used. This is set along with setting the check_same_thread parameter to False. │ │ │ │ │ +It has been observed that the previous approach of defaulting to _N_u_l_l_P_o_o_l, │ │ │ │ │ +which does not hold onto database connections after they are released, did in │ │ │ │ │ +fact have a measurable negative performance impact. As always, the pool class │ │ │ │ │ +is customizable via the _c_r_e_a_t_e___e_n_g_i_n_e_._p_o_o_l_c_l_a_s_s parameter. │ │ │ │ │ +See also │ │ │ │ │ +_T_h_e_ _S_Q_L_i_t_e_ _d_i_a_l_e_c_t_ _u_s_e_s_ _Q_u_e_u_e_P_o_o_l_ _f_o_r_ _f_i_l_e_-_b_a_s_e_d_ _d_a_t_a_b_a_s_e_s │ │ │ │ │ +References: _#_7_4_9_0 │ │ │ │ │ ******** mmssssqqll_?¶ ******** │ │ │ │ │ * [[mmssssqqll]] [[uusseeccaassee]] _¶ │ │ │ │ │ Implemented reflection of the “clustered index” flag mssql_clustered for │ │ │ │ │ the SQL Server dialect. Pull request courtesy John Lennox. │ │ │ │ │ References: _#_8_2_8_8 │ │ │ │ │ [[mmssssqqll]] [[uusseeccaassee]] _¶ │ │ │ │ │ Added support table and column comments on MSSQL when creating a table. Added │ │ │ ├── ./usr/share/doc/python-sqlalchemy-doc/html/orm/examples.html │ │ │ │┄ Ordering differences only │ │ │ │ @@ -319,28 +319,28 @@ │ │ │ │
│ │ │ │

│ │ │ │
│ │ │ │
│ │ │ │

Asyncio Integration

│ │ │ │

Examples illustrating the asyncio engine feature of SQLAlchemy.

│ │ │ │

Listing of files:

    │ │ │ │ -
  • basic.py - Illustrates the asyncio engine / connection interface.

    │ │ │ │ -

  • │ │ │ │ -
  • greenlet_orm.py - Illustrates use of the sqlalchemy.ext.asyncio.AsyncSession object │ │ │ │ -for asynchronous ORM use, including the optional run_sync() method.

    │ │ │ │ +
  • async_orm_writeonly.py - Illustrates using write only relationships for simpler handling │ │ │ │ +of ORM collections under asyncio.

    │ │ │ │

  • │ │ │ │
  • async_orm.py - Illustrates use of the sqlalchemy.ext.asyncio.AsyncSession object │ │ │ │ for asynchronous ORM use.

    │ │ │ │

  • │ │ │ │
  • gather_orm_statements.py - Illustrates how to run many statements concurrently using asyncio.gather() │ │ │ │ along many asyncio database connections, merging ORM results into a single │ │ │ │ AsyncSession.

    │ │ │ │

  • │ │ │ │ -
  • async_orm_writeonly.py - Illustrates using write only relationships for simpler handling │ │ │ │ -of ORM collections under asyncio.

    │ │ │ │ +
  • greenlet_orm.py - Illustrates use of the sqlalchemy.ext.asyncio.AsyncSession object │ │ │ │ +for asynchronous ORM use, including the optional run_sync() method.

    │ │ │ │ +

  • │ │ │ │ +
  • basic.py - Illustrates the asyncio engine / connection interface.

    │ │ │ │

  • │ │ │ │
│ │ │ │

│ │ │ │
│ │ │ │
│ │ │ │

Directed Graphs

│ │ │ │

An example of persistence for a directed graph structure. The │ │ │ │ @@ -385,23 +385,23 @@ │ │ │ │

  • generic_fk.py - Illustrates a so-called “generic foreign key”, in a similar fashion │ │ │ │ to that of popular frameworks such as Django, ROR, etc. This │ │ │ │ approach bypasses standard referential integrity │ │ │ │ practices, in that the “foreign key” column is not actually │ │ │ │ constrained to refer to any particular table; instead, │ │ │ │ in-application logic is used to determine which table is referenced.

    │ │ │ │

  • │ │ │ │ -
  • table_per_related.py - Illustrates a generic association which persists association │ │ │ │ -objects within individual tables, each one generated to persist │ │ │ │ -those objects on behalf of a particular parent class.

    │ │ │ │ -

  • │ │ │ │
  • table_per_association.py - Illustrates a mixin which provides a generic association │ │ │ │ via a individually generated association tables for each parent class. │ │ │ │ The associated objects themselves are persisted in a single table │ │ │ │ shared among all parents.

    │ │ │ │

  • │ │ │ │ +
  • table_per_related.py - Illustrates a generic association which persists association │ │ │ │ +objects within individual tables, each one generated to persist │ │ │ │ +those objects on behalf of a particular parent class.

    │ │ │ │ +

  • │ │ │ │
  • discriminator_on_association.py - Illustrates a mixin which provides a generic association │ │ │ │ using a single target table and a single association table, │ │ │ │ referred to by all parent tables. The association table │ │ │ │ contains a “discriminator” column which determines what type of │ │ │ │ parent object associates to each particular row in the association │ │ │ │ table.

    │ │ │ │

  • │ │ │ │ @@ -477,32 +477,32 @@ │ │ │ │
    │ │ │ │

    See also

    │ │ │ │

    How can I profile a SQLAlchemy powered application?

    │ │ │ │
    │ │ │ │
    │ │ │ │

    File Listing

    │ │ │ │

    Listing of files:

      │ │ │ │ -
    • bulk_updates.py - This series of tests will illustrate different ways to UPDATE a large number │ │ │ │ -of rows in bulk (under construction! there’s just one test at the moment)

      │ │ │ │ +
    • large_resultsets.py - In this series of tests, we are looking at time to load a large number │ │ │ │ +of very small and simple rows.

      │ │ │ │ +

    • │ │ │ │ +
    • __main__.py - Allows the examples/performance package to be run as a script.

      │ │ │ │

    • │ │ │ │
    • bulk_inserts.py - This series of tests illustrates different ways to INSERT a large number │ │ │ │ of rows in bulk.

      │ │ │ │

    • │ │ │ │ -
    • single_inserts.py - In this series of tests, we’re looking at a method that inserts a row │ │ │ │ -within a distinct transaction, and afterwards returns to essentially a │ │ │ │ -“closed” state. This would be analogous to an API call that starts up │ │ │ │ -a database connection, inserts the row, commits and closes.

      │ │ │ │ +
    • bulk_updates.py - This series of tests will illustrate different ways to UPDATE a large number │ │ │ │ +of rows in bulk (under construction! there’s just one test at the moment)

      │ │ │ │

    • │ │ │ │
    • short_selects.py - This series of tests illustrates different ways to SELECT a single │ │ │ │ record by primary key

      │ │ │ │

    • │ │ │ │ -
    • __main__.py - Allows the examples/performance package to be run as a script.

      │ │ │ │ -

    • │ │ │ │ -
    • large_resultsets.py - In this series of tests, we are looking at time to load a large number │ │ │ │ -of very small and simple rows.

      │ │ │ │ +
    • single_inserts.py - In this series of tests, we’re looking at a method that inserts a row │ │ │ │ +within a distinct transaction, and afterwards returns to essentially a │ │ │ │ +“closed” state. This would be analogous to an API call that starts up │ │ │ │ +a database connection, inserts the row, commits and closes.

      │ │ │ │

    • │ │ │ │
    │ │ │ │

    │ │ │ │
    │ │ │ │
    │ │ │ │

    Running all tests with time

    │ │ │ │

    This is the default form of run:

    │ │ │ │ @@ -751,22 +751,22 @@ │ │ │ │

    Several examples that illustrate the technique of intercepting changes │ │ │ │ that would be first interpreted as an UPDATE on a row, and instead turning │ │ │ │ it into an INSERT of a new row, leaving the previous row intact as │ │ │ │ a historical version.

    │ │ │ │

    Compare to the Versioning with a History Table example which writes a │ │ │ │ history row to a separate history table.

    │ │ │ │

    Listing of files:

      │ │ │ │ -
    • versioned_map.py - A variant of the versioned_rows example built around the │ │ │ │ -concept of a “vertical table” structure, like those illustrated in │ │ │ │ -Vertical Attribute Mapping examples.

      │ │ │ │ -

    • │ │ │ │
    • versioned_rows.py - Illustrates a method to intercept changes on objects, turning │ │ │ │ an UPDATE statement on a single row into an INSERT statement, so that a new │ │ │ │ row is inserted with the new data, keeping the old row intact.

      │ │ │ │

    • │ │ │ │ +
    • versioned_map.py - A variant of the versioned_rows example built around the │ │ │ │ +concept of a “vertical table” structure, like those illustrated in │ │ │ │ +Vertical Attribute Mapping examples.

      │ │ │ │ +

    • │ │ │ │
    • versioned_rows_w_versionid.py - Illustrates a method to intercept changes on objects, turning │ │ │ │ an UPDATE statement on a single row into an INSERT statement, so that a new │ │ │ │ row is inserted with the new data, keeping the old row intact.

      │ │ │ │

    • │ │ │ │
    • versioned_update_old_row.py - Illustrates the same UPDATE into INSERT technique of versioned_rows.py, │ │ │ │ but also emits an UPDATE on the old row to affect a change in timestamp. │ │ │ │ Also includes a SessionEvents.do_orm_execute() hook to limit queries │ │ │ │ @@ -815,41 +815,41 @@ │ │ │ │

      │ │ │ │

      Inheritance Mapping Recipes

      │ │ │ │
      │ │ │ │

      Basic Inheritance Mappings

      │ │ │ │

      Working examples of single-table, joined-table, and concrete-table │ │ │ │ inheritance as described in Mapping Class Inheritance Hierarchies.

      │ │ │ │

      Listing of files:

        │ │ │ │ -
      • joined.py - Joined-table (table-per-subclass) inheritance example.

        │ │ │ │ +
      • concrete.py - Concrete-table (table-per-class) inheritance example.

        │ │ │ │

      • │ │ │ │
      • single.py - Single-table (table-per-hierarchy) inheritance example.

        │ │ │ │

      • │ │ │ │ -
      • concrete.py - Concrete-table (table-per-class) inheritance example.

        │ │ │ │ +
      • joined.py - Joined-table (table-per-subclass) inheritance example.

        │ │ │ │

      • │ │ │ │
      │ │ │ │

      │ │ │ │
      │ │ │ │
      │ │ │ │
      │ │ │ │

      Special APIs

      │ │ │ │
      │ │ │ │

      Attribute Instrumentation

      │ │ │ │

      Examples illustrating modifications to SQLAlchemy’s attribute management │ │ │ │ system.

      │ │ │ │

      Listing of files:

        │ │ │ │ -
      • active_column_defaults.py - Illustrates use of the AttributeEvents.init_scalar() │ │ │ │ -event, in conjunction with Core column defaults to provide │ │ │ │ -ORM objects that automatically produce the default value │ │ │ │ -when an un-set attribute is accessed.

        │ │ │ │ +
      • listen_for_events.py - Illustrates how to attach events to all instrumented attributes │ │ │ │ +and listen for change events.

        │ │ │ │

      • │ │ │ │
      • custom_management.py - Illustrates customized class instrumentation, using │ │ │ │ the sqlalchemy.ext.instrumentation extension package.

        │ │ │ │

      • │ │ │ │ -
      • listen_for_events.py - Illustrates how to attach events to all instrumented attributes │ │ │ │ -and listen for change events.

        │ │ │ │ +
      • active_column_defaults.py - Illustrates use of the AttributeEvents.init_scalar() │ │ │ │ +event, in conjunction with Core column defaults to provide │ │ │ │ +ORM objects that automatically produce the default value │ │ │ │ +when an un-set attribute is accessed.

        │ │ │ │

      • │ │ │ │
      │ │ │ │

      │ │ │ │
      │ │ │ │
      │ │ │ │

      Horizontal Sharding

      │ │ │ │

      A basic example of using the SQLAlchemy Sharding API. │ │ │ │ @@ -879,24 +879,24 @@ │ │ │ │

      The construction of generic sharding routines is an ambitious approach │ │ │ │ to the issue of organizing instances among multiple databases. For a │ │ │ │ more plain-spoken alternative, the “distinct entity” approach │ │ │ │ is a simple method of assigning objects to different tables (and potentially │ │ │ │ database nodes) in an explicit way - described on the wiki at │ │ │ │ EntityName.

      │ │ │ │

      Listing of files:

        │ │ │ │ -
      • asyncio.py - Illustrates sharding API used with asyncio.

        │ │ │ │ -

      • │ │ │ │
      • separate_tables.py - Illustrates sharding using a single SQLite database, that will however │ │ │ │ have multiple tables using a naming convention.

        │ │ │ │

      • │ │ │ │ +
      • separate_databases.py - Illustrates sharding using distinct SQLite databases.

        │ │ │ │ +

      • │ │ │ │ +
      • asyncio.py - Illustrates sharding API used with asyncio.

        │ │ │ │ +

      • │ │ │ │
      • separate_schema_translates.py - Illustrates sharding using a single database with multiple schemas, │ │ │ │ where a different “schema_translates_map” can be used for each shard.

        │ │ │ │

      • │ │ │ │ -
      • separate_databases.py - Illustrates sharding using distinct SQLite databases.

        │ │ │ │ -

      • │ │ │ │
      │ │ │ │

      │ │ │ │
      │ │ │ │
      │ │ │ │
      │ │ │ │

      Extending the ORM

      │ │ │ │
      │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -109,24 +109,24 @@ │ │ │ │ │ values, which conceal the underlying mapped classes. │ │ │ │ │ _b_a_s_i_c___a_s_s_o_c_i_a_t_i_o_n_._p_y - Illustrate a many-to-many relationship between an │ │ │ │ │ “Order” and a collection of “Item” objects, associating a purchase price with │ │ │ │ │ each via an association object called “OrderItem” │ │ │ │ │ ******** AAssyynncciioo IInntteeggrraattiioonn_?¶ ******** │ │ │ │ │ Examples illustrating the asyncio engine feature of SQLAlchemy. │ │ │ │ │ Listing of files: │ │ │ │ │ - * _b_a_s_i_c_._p_y - Illustrates the asyncio engine / connection interface. │ │ │ │ │ -_g_r_e_e_n_l_e_t___o_r_m_._p_y - Illustrates use of the sqlalchemy.ext.asyncio.AsyncSession │ │ │ │ │ -object for asynchronous ORM use, including the optional run_sync() method. │ │ │ │ │ + * _a_s_y_n_c___o_r_m___w_r_i_t_e_o_n_l_y_._p_y - Illustrates using wwrriittee oonnllyy rreellaattiioonnsshhiippss for │ │ │ │ │ + simpler handling of ORM collections under asyncio. │ │ │ │ │ _a_s_y_n_c___o_r_m_._p_y - Illustrates use of the sqlalchemy.ext.asyncio.AsyncSession │ │ │ │ │ object for asynchronous ORM use. │ │ │ │ │ _g_a_t_h_e_r___o_r_m___s_t_a_t_e_m_e_n_t_s_._p_y - Illustrates how to run many statements concurrently │ │ │ │ │ using asyncio.gather() along many asyncio database connections, merging ORM │ │ │ │ │ results into a single AsyncSession. │ │ │ │ │ -_a_s_y_n_c___o_r_m___w_r_i_t_e_o_n_l_y_._p_y - Illustrates using wwrriittee oonnllyy rreellaattiioonnsshhiippss for simpler │ │ │ │ │ -handling of ORM collections under asyncio. │ │ │ │ │ +_g_r_e_e_n_l_e_t___o_r_m_._p_y - Illustrates use of the sqlalchemy.ext.asyncio.AsyncSession │ │ │ │ │ +object for asynchronous ORM use, including the optional run_sync() method. │ │ │ │ │ +_b_a_s_i_c_._p_y - Illustrates the asyncio engine / connection interface. │ │ │ │ │ ******** DDiirreecctteedd GGrraapphhss_?¶ ******** │ │ │ │ │ An example of persistence for a directed graph structure. The graph is stored │ │ │ │ │ as a collection of edges, each referencing both a “lower” and an “upper” node │ │ │ │ │ in a table of nodes. Basic persistence and querying for lower- and upper- │ │ │ │ │ neighbors are illustrated: │ │ │ │ │ n2 = Node(2) │ │ │ │ │ n5 = Node(5) │ │ │ │ │ @@ -154,21 +154,21 @@ │ │ │ │ │ Listing of files: │ │ │ │ │ * _g_e_n_e_r_i_c___f_k_._p_y - Illustrates a so-called “generic foreign key”, in a │ │ │ │ │ similar fashion to that of popular frameworks such as Django, ROR, etc. │ │ │ │ │ This approach bypasses standard referential integrity practices, in that │ │ │ │ │ the “foreign key” column is not actually constrained to refer to any │ │ │ │ │ particular table; instead, in-application logic is used to determine │ │ │ │ │ which table is referenced. │ │ │ │ │ -_t_a_b_l_e___p_e_r___r_e_l_a_t_e_d_._p_y - Illustrates a generic association which persists │ │ │ │ │ -association objects within individual tables, each one generated to persist │ │ │ │ │ -those objects on behalf of a particular parent class. │ │ │ │ │ _t_a_b_l_e___p_e_r___a_s_s_o_c_i_a_t_i_o_n_._p_y - Illustrates a mixin which provides a generic │ │ │ │ │ association via a individually generated association tables for each parent │ │ │ │ │ class. The associated objects themselves are persisted in a single table shared │ │ │ │ │ among all parents. │ │ │ │ │ +_t_a_b_l_e___p_e_r___r_e_l_a_t_e_d_._p_y - Illustrates a generic association which persists │ │ │ │ │ +association objects within individual tables, each one generated to persist │ │ │ │ │ +those objects on behalf of a particular parent class. │ │ │ │ │ _d_i_s_c_r_i_m_i_n_a_t_o_r___o_n___a_s_s_o_c_i_a_t_i_o_n_._p_y - Illustrates a mixin which provides a generic │ │ │ │ │ association using a single target table and a single association table, │ │ │ │ │ referred to by all parent tables. The association table contains a │ │ │ │ │ “discriminator” column which determines what type of parent object associates │ │ │ │ │ to each particular row in the association table. │ │ │ │ │ ******** MMaatteerriiaalliizzeedd PPaatthhss_?¶ ******** │ │ │ │ │ Illustrates the “materialized paths” pattern for hierarchical data using the │ │ │ │ │ @@ -221,28 +221,28 @@ │ │ │ │ │ $ python -m examples.performance bulk_inserts \ │ │ │ │ │ --dburl mysql+mysqldb://scott:tiger@localhost/test \ │ │ │ │ │ --profile --num 1000 │ │ │ │ │ See also │ │ │ │ │ _H_o_w_ _c_a_n_ _I_ _p_r_o_f_i_l_e_ _a_ _S_Q_L_A_l_c_h_e_m_y_ _p_o_w_e_r_e_d_ _a_p_p_l_i_c_a_t_i_o_n_? │ │ │ │ │ ****** FFiillee LLiissttiinngg_?¶ ****** │ │ │ │ │ Listing of files: │ │ │ │ │ - * _b_u_l_k___u_p_d_a_t_e_s_._p_y - This series of tests will illustrate different ways to │ │ │ │ │ - UPDATE a large number of rows in bulk (under construction! there’s just │ │ │ │ │ - one test at the moment) │ │ │ │ │ + * _l_a_r_g_e___r_e_s_u_l_t_s_e_t_s_._p_y - In this series of tests, we are looking at time to │ │ │ │ │ + load a large number of very small and simple rows. │ │ │ │ │ +_____m_a_i_n_____._p_y - Allows the examples/performance package to be run as a script. │ │ │ │ │ _b_u_l_k___i_n_s_e_r_t_s_._p_y - This series of tests illustrates different ways to INSERT a │ │ │ │ │ large number of rows in bulk. │ │ │ │ │ +_b_u_l_k___u_p_d_a_t_e_s_._p_y - This series of tests will illustrate different ways to UPDATE │ │ │ │ │ +a large number of rows in bulk (under construction! there’s just one test at │ │ │ │ │ +the moment) │ │ │ │ │ +_s_h_o_r_t___s_e_l_e_c_t_s_._p_y - This series of tests illustrates different ways to SELECT a │ │ │ │ │ +single record by primary key │ │ │ │ │ _s_i_n_g_l_e___i_n_s_e_r_t_s_._p_y - In this series of tests, we’re looking at a method that │ │ │ │ │ inserts a row within a distinct transaction, and afterwards returns to │ │ │ │ │ essentially a “closed” state. This would be analogous to an API call that │ │ │ │ │ starts up a database connection, inserts the row, commits and closes. │ │ │ │ │ -_s_h_o_r_t___s_e_l_e_c_t_s_._p_y - This series of tests illustrates different ways to SELECT a │ │ │ │ │ -single record by primary key │ │ │ │ │ -_____m_a_i_n_____._p_y - Allows the examples/performance package to be run as a script. │ │ │ │ │ -_l_a_r_g_e___r_e_s_u_l_t_s_e_t_s_._p_y - In this series of tests, we are looking at time to load a │ │ │ │ │ -large number of very small and simple rows. │ │ │ │ │ ****** RRuunnnniinngg aallll tteessttss wwiitthh ttiimmee_?¶ ****** │ │ │ │ │ This is the default form of run: │ │ │ │ │ $ python -m examples.performance single_inserts │ │ │ │ │ Tests to run: test_orm_commit, test_bulk_save, │ │ │ │ │ test_bulk_insert_dictionaries, test_core, │ │ │ │ │ test_core_query_caching, test_dbapi_raw_w_connect, │ │ │ │ │ test_dbapi_raw_w_pool │ │ │ │ │ @@ -468,20 +468,20 @@ │ │ │ │ │ Several examples that illustrate the technique of intercepting changes that │ │ │ │ │ would be first interpreted as an UPDATE on a row, and instead turning it into │ │ │ │ │ an INSERT of a new row, leaving the previous row intact as a historical │ │ │ │ │ version. │ │ │ │ │ Compare to the _V_e_r_s_i_o_n_i_n_g_ _w_i_t_h_ _a_ _H_i_s_t_o_r_y_ _T_a_b_l_e example which writes a history │ │ │ │ │ row to a separate history table. │ │ │ │ │ Listing of files: │ │ │ │ │ - * _v_e_r_s_i_o_n_e_d___m_a_p_._p_y - A variant of the versioned_rows example built around │ │ │ │ │ - the concept of a “vertical table” structure, like those illustrated in │ │ │ │ │ - _V_e_r_t_i_c_a_l_ _A_t_t_r_i_b_u_t_e_ _M_a_p_p_i_n_g examples. │ │ │ │ │ -_v_e_r_s_i_o_n_e_d___r_o_w_s_._p_y - Illustrates a method to intercept changes on objects, │ │ │ │ │ -turning an UPDATE statement on a single row into an INSERT statement, so that a │ │ │ │ │ -new row is inserted with the new data, keeping the old row intact. │ │ │ │ │ + * _v_e_r_s_i_o_n_e_d___r_o_w_s_._p_y - Illustrates a method to intercept changes on objects, │ │ │ │ │ + turning an UPDATE statement on a single row into an INSERT statement, so │ │ │ │ │ + that a new row is inserted with the new data, keeping the old row intact. │ │ │ │ │ +_v_e_r_s_i_o_n_e_d___m_a_p_._p_y - A variant of the versioned_rows example built around the │ │ │ │ │ +concept of a “vertical table” structure, like those illustrated in _V_e_r_t_i_c_a_l │ │ │ │ │ +_A_t_t_r_i_b_u_t_e_ _M_a_p_p_i_n_g examples. │ │ │ │ │ _v_e_r_s_i_o_n_e_d___r_o_w_s___w___v_e_r_s_i_o_n_i_d_._p_y - Illustrates a method to intercept changes on │ │ │ │ │ objects, turning an UPDATE statement on a single row into an INSERT statement, │ │ │ │ │ so that a new row is inserted with the new data, keeping the old row intact. │ │ │ │ │ _v_e_r_s_i_o_n_e_d___u_p_d_a_t_e___o_l_d___r_o_w_._p_y - Illustrates the same UPDATE into INSERT technique │ │ │ │ │ of versioned_rows.py, but also emits an UPDATE on the oolldd row to affect a │ │ │ │ │ change in timestamp. Also includes a _S_e_s_s_i_o_n_E_v_e_n_t_s_._d_o___o_r_m___e_x_e_c_u_t_e_(_) hook to │ │ │ │ │ limit queries to only the most recent version. │ │ │ │ │ @@ -515,30 +515,29 @@ │ │ │ │ │ _d_i_c_t_l_i_k_e_-_p_o_l_y_m_o_r_p_h_i_c_._p_y - Mapping a polymorphic-valued vertical table as a │ │ │ │ │ dictionary. │ │ │ │ │ ********** IInnhheerriittaannccee MMaappppiinngg RReecciippeess_?¶ ********** │ │ │ │ │ ******** BBaassiicc IInnhheerriittaannccee MMaappppiinnggss_?¶ ******** │ │ │ │ │ Working examples of single-table, joined-table, and concrete-table inheritance │ │ │ │ │ as described in _M_a_p_p_i_n_g_ _C_l_a_s_s_ _I_n_h_e_r_i_t_a_n_c_e_ _H_i_e_r_a_r_c_h_i_e_s. │ │ │ │ │ Listing of files: │ │ │ │ │ - * _j_o_i_n_e_d_._p_y - Joined-table (table-per-subclass) inheritance example. │ │ │ │ │ + * _c_o_n_c_r_e_t_e_._p_y - Concrete-table (table-per-class) inheritance example. │ │ │ │ │ _s_i_n_g_l_e_._p_y - Single-table (table-per-hierarchy) inheritance example. │ │ │ │ │ -_c_o_n_c_r_e_t_e_._p_y - Concrete-table (table-per-class) inheritance example. │ │ │ │ │ +_j_o_i_n_e_d_._p_y - Joined-table (table-per-subclass) inheritance example. │ │ │ │ │ ********** SSppeecciiaall AAPPIIss_?¶ ********** │ │ │ │ │ ******** AAttttrriibbuuttee IInnssttrruummeennttaattiioonn_?¶ ******** │ │ │ │ │ Examples illustrating modifications to SQLAlchemy’s attribute management │ │ │ │ │ system. │ │ │ │ │ Listing of files: │ │ │ │ │ - * _a_c_t_i_v_e___c_o_l_u_m_n___d_e_f_a_u_l_t_s_._p_y - Illustrates use of the │ │ │ │ │ - _A_t_t_r_i_b_u_t_e_E_v_e_n_t_s_._i_n_i_t___s_c_a_l_a_r_(_) event, in conjunction with Core column │ │ │ │ │ - defaults to provide ORM objects that automatically produce the default │ │ │ │ │ - value when an un-set attribute is accessed. │ │ │ │ │ + * _l_i_s_t_e_n___f_o_r___e_v_e_n_t_s_._p_y - Illustrates how to attach events to all │ │ │ │ │ + instrumented attributes and listen for change events. │ │ │ │ │ _c_u_s_t_o_m___m_a_n_a_g_e_m_e_n_t_._p_y - Illustrates customized class instrumentation, using the │ │ │ │ │ _s_q_l_a_l_c_h_e_m_y_._e_x_t_._i_n_s_t_r_u_m_e_n_t_a_t_i_o_n extension package. │ │ │ │ │ -_l_i_s_t_e_n___f_o_r___e_v_e_n_t_s_._p_y - Illustrates how to attach events to all instrumented │ │ │ │ │ -attributes and listen for change events. │ │ │ │ │ +_a_c_t_i_v_e___c_o_l_u_m_n___d_e_f_a_u_l_t_s_._p_y - Illustrates use of the _A_t_t_r_i_b_u_t_e_E_v_e_n_t_s_._i_n_i_t___s_c_a_l_a_r │ │ │ │ │ +_(_) event, in conjunction with Core column defaults to provide ORM objects that │ │ │ │ │ +automatically produce the default value when an un-set attribute is accessed. │ │ │ │ │ ******** HHoorriizzoonnttaall SShhaarrddiinngg_?¶ ******** │ │ │ │ │ A basic example of using the SQLAlchemy Sharding API. Sharding refers to │ │ │ │ │ horizontally scaling data across multiple databases. │ │ │ │ │ The basic components of a “sharded” mapping are: │ │ │ │ │ * multiple _E_n_g_i_n_e instances, each assigned a “shard id”. These _E_n_g_i_n_e │ │ │ │ │ instances may refer to different databases, or different schemas / │ │ │ │ │ accounts within the same database, or they can even be differentiated │ │ │ │ │ @@ -559,21 +558,21 @@ │ │ │ │ │ attempt to determine a single shard being requested. │ │ │ │ │ The construction of generic sharding routines is an ambitious approach to the │ │ │ │ │ issue of organizing instances among multiple databases. For a more plain-spoken │ │ │ │ │ alternative, the “distinct entity” approach is a simple method of assigning │ │ │ │ │ objects to different tables (and potentially database nodes) in an explicit way │ │ │ │ │ - described on the wiki at _E_n_t_i_t_y_N_a_m_e. │ │ │ │ │ Listing of files: │ │ │ │ │ - * _a_s_y_n_c_i_o_._p_y - Illustrates sharding API used with asyncio. │ │ │ │ │ -_s_e_p_a_r_a_t_e___t_a_b_l_e_s_._p_y - Illustrates sharding using a single SQLite database, that │ │ │ │ │ -will however have multiple tables using a naming convention. │ │ │ │ │ + * _s_e_p_a_r_a_t_e___t_a_b_l_e_s_._p_y - Illustrates sharding using a single SQLite database, │ │ │ │ │ + that will however have multiple tables using a naming convention. │ │ │ │ │ +_s_e_p_a_r_a_t_e___d_a_t_a_b_a_s_e_s_._p_y - Illustrates sharding using distinct SQLite databases. │ │ │ │ │ +_a_s_y_n_c_i_o_._p_y - Illustrates sharding API used with asyncio. │ │ │ │ │ _s_e_p_a_r_a_t_e___s_c_h_e_m_a___t_r_a_n_s_l_a_t_e_s_._p_y - Illustrates sharding using a single database │ │ │ │ │ with multiple schemas, where a different “schema_translates_map” can be used │ │ │ │ │ for each shard. │ │ │ │ │ -_s_e_p_a_r_a_t_e___d_a_t_a_b_a_s_e_s_._p_y - Illustrates sharding using distinct SQLite databases. │ │ │ │ │ ********** EExxtteennddiinngg tthhee OORRMM_?¶ ********** │ │ │ │ │ ******** OORRMM QQuueerryy EEvveennttss_?¶ ******** │ │ │ │ │ Recipes which illustrate augmentation of ORM SELECT behavior as used by │ │ │ │ │ _S_e_s_s_i_o_n_._e_x_e_c_u_t_e_(_) with _2_._0_ _s_t_y_l_e use of _s_e_l_e_c_t_(_), as well as the _1_._x_ _s_t_y_l_e │ │ │ │ │ _Q_u_e_r_y object. │ │ │ │ │ Examples include demonstrations of the _w_i_t_h___l_o_a_d_e_r___c_r_i_t_e_r_i_a_(_) option as well as │ │ │ │ │ the _S_e_s_s_i_o_n_E_v_e_n_t_s_._d_o___o_r_m___e_x_e_c_u_t_e_(_) hook.