2.0 Changelog

2.0.16

Released: June 10, 2023

platform

  • [platform] [usecase]

    Улучшена совместимость, благодаря чему весь набор тестов работает на Python 3.12.0b1.

orm

  • [orm] [usecase]

    Улучшена функция DeferredReflection.prepare() для приема произвольных аргументов **kw, передаваемых в MetaData.reflect(), что позволяет использовать такие случаи, как отражение представлений, а также передавать аргументы, специфичные для диалекта. Кроме того, модернизирован аргумент DeferredReflection.prepare.bind так, что в качестве аргумента «bind» принимается либо Engine, либо Connection.

    References: #9828

  • [orm] [bug]

    Исправлена проблема, когда декларативный базовый класс DeclarativeBaseNoMeta не работал с не отображенными миксинами или абстрактными классами, вызывая вместо этого ошибку AttributeError.

    References: #9862

  • [orm] [bug] [regression]

    В серии 2.0 исправлена регрессия, при которой значение по умолчанию validates.include_backrefs для функции validates() менялось на False. Теперь это значение по умолчанию восстановлено до True.

    References: #9820

  • [orm] [bug]

    Исправлена ошибка в новой функции, позволяющей использовать предложение WHERE в сочетании с ORM Bulk UPDATE по первичному ключу, добавленной в версии 2.0.11 как часть #9583, когда при отправке словарей, не содержащих значений первичных ключей для каждой строки, выполнялся массовый процесс, включающий «pk=NULL» для этих строк, что приводило к молчаливому отказу. Теперь при отсутствии значений первичных ключей для массового UPDATE выдается исключение.

    References: #9917

  • [orm] [bug] [dataclasses]

    Исправлена проблема, при которой не работала генерация полей dataclasses, задающих значение default и устанавливающих значение init=False. Поведение dataclasses в этом случае заключается в установке значения по умолчанию для класса, что несовместимо с дескрипторами, используемыми SQLAlchemy. Для поддержки этого случая значение по умолчанию преобразуется в default_factory при генерации класса данных.

    References: #9879

  • [orm] [bug]

    Предупреждение об устаревании выдается всякий раз, когда свойство добавляется в Mapper, где уже было настроено свойство, сопоставленное с ORM, или атрибут уже присутствует в классе. Ранее для этого случая существовало предупреждение, не связанное с депривацией, которое выдавалось непоследовательно. Логика работы этого предупреждения была улучшена таким образом, чтобы оно обнаруживало замену атрибута конечным пользователем и не давало ложных срабатываний для внутренних декларативных и других случаев, когда ожидается замена дескрипторов на новые.

    References: #9841

  • [orm] [bug]

    Улучшен отбор аргументов для параметра map_imperatively.local_table метода registry.map_imperatively(), обеспечивающий передачу только Table или другого FromClause, а не существующего маппированного класса, что привело бы к неопределенному поведению при дальнейшей интерпретации объекта для нового маппинга.

    References: #9869

  • [orm] [bug]

    Атрибут InstanceState.unloaded_expirable является синонимом атрибута InstanceState.unloaded и в настоящее время устарел; этот атрибут всегда был специфичен для конкретной реализации и не должен был быть общедоступным.

    References: #9913

asyncio

  • [asyncio] [usecase]

    В create_async_engine() добавлен новый параметр create_async_engine.async_creator, который выполняет ту же задачу, что и параметр create_engine.creator в create_engine(). Это неаргументированный вызываемый параметр, который обеспечивает новое asyncio-соединение, используя непосредственно драйвер базы данных asyncio. Функция create_async_engine() обернет соединение на уровне драйвера в соответствующие структуры. Pull request curtesy of Jack Wotherspoon.

    References: #8215

postgresql

  • [postgresql] [usecase] [reflection]

    Приведение столбцов NAME к TEXT при использовании ARRAY_AGG в отражении PostgreSQL. Это, по-видимому, улучшает совместимость с некоторыми производными PostgreSQL, которые могут не поддерживать агрегирование по типу NAME.

    References: #9838

  • [postgresql] [usecase]

    Унифицированные определения пользовательских операторов PostgreSQL, поскольку они являются общими для нескольких различных типов данных.

    References: #9041

  • [postgresql] [usecase]

    Добавлена поддержка в PostgreSQL 10 NULLS NOT DISTINCT особенности уникальных индексов и уникальных ограничений с использованием опции диалекта postgresql_nulls_not_distinct. Обновлена логика отражения, которая также корректно учитывает эту опцию. Pull request любезно предоставлен Павлом Сиарченя.

    References: #8240

  • [postgresql] [bug]

    Использование правильного старшинства для специфических операторов PostgreSQL, таких как @>. Ранее предшествование было неверным, что приводило к неправильному выводу скобок при выводе на экран конструкции ANY или ALL.

    References: #9836

  • [postgresql] [bug]

    Исправлена проблема, когда параметры ColumnOperators.like.escape и подобные им не допускали в качестве аргумента пустую строку, которая передавалась как символ «escape»; такой синтаксис поддерживается PostgreSQL. Pull requset любезно предоставлен Мартином Каславски.

    References: #9907

2.0.15

Released: May 19, 2023

orm

  • [orm] [bug]

    По мере того, как все больше проектов используют ORM-запросы нового стиля «2.0», становится очевидным, что условный характер «autoflush», основанный на том, ссылается ли данный оператор на ORM-сущности, становится все более ключевым поведением. До сих пор флаг «ORM» для утверждения был слабо связан с тем, возвращает ли утверждение строки, соответствующие ORM-сущностям или столбцам; первоначальное назначение флага «ORM» заключалось в том, чтобы включить правила выборки ORM-сущностей, которые применяют постобработку к наборам результатов Core, а также стратегии ORM-загрузчика к утверждению. Для операторов, не опирающихся на строки, содержащие ORM-сущности, флаг «ORM» был признан практически ненужным.

    Может оказаться, что «autoflush» лучше использовать для всех случаев использования Session.execute() и связанных с ним методов, даже для чисто Core SQL-конструкций. Однако это все еще может повлиять на старые случаи, где этого не ожидается, и, возможно, это больше относится к версии 2.1. Однако на данный момент правила для «ORM-флага» были открыты таким образом, что оператор, включающий ORM-сущности или атрибуты в любом месте, в том числе в одном только предложении WHERE / ORDER BY / GROUP BY, в скалярных подзапросах и т.д., будет включать этот флаг. Это вызовет «автопромывку» для таких операторов, а также будет видно по атрибуту уровня события ORMExecuteState.is_orm_statement.

    References: #9805

postgresql

  • [postgresql] [bug] [regression]

    Исправлен базовый тип данных Uuid для диалекта PostgreSQL, чтобы при выборе «native_uuid» полностью использовался специфичный для диалекта PG тип данных UUID, что позволяет учитывать поведение драйвера PG. Эта проблема стала очевидной в связи с улучшением insertmanyvalues, сделанным в рамках #9618, где, как и в #9739, драйвер asyncpg очень чувствителен к наличию или отсутствию приведения типов данных, и специфичный для драйвера PostgreSQL родной тип данных UUID должен быть вызван при использовании этого общего типа, чтобы эти приведения имели место.

    References: #9808

2.0.14

Released: May 18, 2023

orm

  • [orm] [bug]

    Модифицирована реализация JoinedLoader для использования более простого подхода в одной конкретной области, где ранее использовалась кэшируемая структура, разделяемая между потоками. Это сделано для того, чтобы избежать потенциального состояния гонки, которое, как предполагается, является причиной конкретного сбоя, о котором неоднократно сообщалось. Кэшируемая структура по-прежнему в конечном итоге «кэшируется» через скомпилированный кэш SQL, поэтому снижения производительности не ожидается.

    References: #9777

  • [orm] [bug] [regression]

    Исправлена ошибка, при которой использование update() или delete() внутри конструкции CTE, а затем в конструкции select() приводило к возникновению ошибки CompileError, связанной с правилами выполнения операторов обновления/удаления на уровне ORM.

    References: #9767

  • [orm] [bug]

    Исправлена проблема в новой ORM Annotated Declarative, когда использование ForeignKey (или другого ограничения на уровне столбцов) внутри mapped_column(), которое затем копируется в модели через pep-593 Annotated, приводило к применению дубликатов каждого ограничения к Column, созданного в целевом Table, что приводило к некорректному DDL CREATE TABLE, а также к директивам миграции под Alembic.

    References: #9766

  • [orm] [bug]

    Исправлена проблема, когда при использовании дополнительных критериев отношений с опцией загрузчика joinedload(), когда сами дополнительные критерии содержали коррелирующие подзапросы, которые ссылались на объединенные сущности и, следовательно, также требовали «адаптации» к алиасным сущностям, эта адаптация исключалась, что приводило к неправильному предложению ON для объединенной загрузки.

    References: #9779

sql

  • [sql] [usecase]

    Обобщение функции MSSQL try_cast() в пространство имен импорта sqlalchemy., чтобы она могла быть реализована и в сторонних диалектах. В SQLAlchemy функция try_cast() остается конструкцией, предназначенной только для SQL Server, и при ее использовании с бэкендами, которые ее не поддерживают, будет возникать ошибка CompileError.

    try_cast() реализует CAST, в котором некастируемые преобразования возвращаются как NULL, а не вызывают ошибку. Теоретически данная конструкция может быть реализована в сторонних диалектах для Google BigQuery, DuckDB, Snowflake и, возможно, других.

    Pull request любезно предоставлен Ником Крюсом.

    References: #9752

  • [sql] [bug]

    Исправлена проблема в конструкции values(), при которой возникала внутренняя ошибка компиляции, если конструкция использовалась внутри скалярного подзапроса.

    References: #9772

postgresql

  • [postgresql] [bug]

    Исправлена очень старая проблема, когда параметр ENUM.create_type, установленный не по умолчанию False, не распространялся при копировании Column, частью которого он является, как это часто бывает при использовании декларативных микшинов ORM.

    References: #9773

tests

  • [tests] [bug] [pypy]

    Исправлен тест, полагающийся на функцию sys.getsizeof(), который не выполнялся на pypy, где эта функция ведет себя иначе, чем на cpython.

    References: #9789

2.0.13

Released: May 10, 2023

orm

  • [orm] [bug]

    Исправлена проблема, при которой ORM Annotated Declarative не во всех случаях корректно разрешала прямые ссылки; в частности, при использовании from __future__ import annotations в сочетании с Pydantic dataclasses.

    References: #9717

  • [orm] [bug]

    Исправлена проблема в новой функции Использование RETURNING в операторах upsert, когда опция выполнения populate_existing не распространялась на опцию загрузки, что не позволяло обновлять существующие атрибуты на месте.

    References: #9746

  • [orm] [bug]

    Исправлены проблемы с траекторией стратегии загрузчика, когда нетерпеливые загрузчики, такие как joinedload() / selectinload(), не могли полностью пройти на много уровней вглубь после загрузки, имеющей в качестве промежуточного члена конструкцию with_polymorphic() или подобную ей.

    References: #9715

  • [orm] [bug]

    Исправлена проблема в конструкции mapped_column(), когда корректное предупреждение «столбец X назван непосредственно несколько раз» не выдавалось, когда ORM mapped атрибуты ссылались на один и тот же Column, если была задействована конструкция mapped_column(), вместо этого выдавалось внутреннее утверждение.

    References: #9630

sql

  • [sql] [usecase]

    Реализовано предупреждение о «картезианском произведении» для операторов UPDATE и DELETE, включающих несколько таблиц, не связанных между собой каким-либо образом.

    References: #9721

  • [sql] [bug]

    Исправлен базовый класс для диалектно-специфических типов float/double; Oracle BINARY_DOUBLE теперь подклассы Double, а внутренние типы Float для asyncpg и pg8000 теперь корректно подклассы Float.

  • [sql] [bug]

    Исправлена проблема, при которой конструкция update(), включающая несколько таблиц и не содержащая предложения VALUES, приводила к внутренней ошибке. Текущее поведение для Update без значений заключается в генерации SQL-оператора UPDATE с пустым предложением «set», поэтому для данного конкретного случая это было сделано единообразно.

schema

  • [schema] [performance]

    Улучшен способ добавления столбцов таблиц, что позволяет избежать лишних выделений и значительно ускорить создание многих таблиц, например, при отражении целых схем.

    References: #9597

typing

  • [typing] [bug]

    Исправлена типизация параметра Session.get.with_for_update в Session.get() и Session.refresh() (а также соответствующих методов на AsyncSession) для принятия булевых True и всех других форм аргументов, принимаемых параметром во время выполнения.

    References: #9762

  • [typing] [sql]

    Добавлен тип ColumnExpressionArgument в качестве публичного типа, указывающего на аргументы, ориентированные на столбцы, которые передаются в конструкции SQLAlchemy, такие как Select.where(), and_() и другие. Это может быть использовано для добавления типизации в функции конечного пользователя, вызывающие эти методы.

    References: #9656

asyncio

  • [asyncio] [usecase]

    Добавлен новый вспомогательный миксин AsyncAttrs, который призван улучшить использование lazy-loader и других ORM-атрибутов с истекшим сроком действия или отложенных атрибутов в asyncio, предоставляя простой атрибутный аксессор, обеспечивающий await интерфейс к любому ORM-атрибуту, независимо от того, нужно ли ему выдавать SQL.

    См.также

    AsyncAttrs

    References: #9731

  • [asyncio] [bug]

    Исправлена проблема в полуприватных функциях параллелизма await_only() и await_fallback(), когда заданный ожидаемый оставался не ожидаемым, если функция выбрасывала GreenletError, что могло привести к появлению предупреждений «не ожидалось» в дальнейшем при продолжении работы программы. В данном случае ожидаемый объект отменяется до того, как будет выброшено исключение.

postgresql

  • [postgresql] [bug] [regression]

    Исправлена еще одна регрессия, связанная с изменением «insertmanyvalues» в версии 2.0.10 в составе #9618, аналогично регрессии #9701, где для работы с новым форматом bulk INSERT для типов данных LargeBinary также требуется дополнительное приведение при использовании драйвера asyncpg.

    References: #9739

oracle

  • [oracle] [reflection]

    В диалекте Oracle добавлена поддержка отражения в индексах, основанных на выражениях, и направления упорядочивания индексных выражений.

    References: #9597

misc

  • [bug] [ext]

    Исправлена проблема в Mutable, когда регистрация событий для атрибутов, отображаемых в ORM, вызывалась повторно для отображаемых подклассов наследования, что приводило к дублированию событий в иерархии наследования.

    References: #9676

2.0.12

Released: April 30, 2023

orm

  • [orm] [bug]

    Исправлена критическая проблема кэширования, когда сочетание композиций выражений aliased() и hybrid_property() приводило к несовпадению ключей кэша, в результате чего ключи кэша удерживали реальный объект aliased() и не совпадали с ключами эквивалентных конструкций, заполняя кэш.

    This change is also backported to: 1.4.48

    References: #9728

mysql

  • [mysql] [bug] [mariadb]

    Исправлены проблемы с отражением комментариев к объектам Table и Column, когда комментарии содержали управляющие символы, такие как новые строки. В целом добавлена поддержка этих символов, а также расширенных символов Unicode в комментариях к таблицам и столбцам (последние не поддерживаются MySQL/MariaDB).

    References: #9722

2.0.11

Released: April 26, 2023

orm

  • [orm] [usecase]

    Функции ORM bulk INSERT and UPDATE теперь добавляют эти возможности:

    • Снято требование не передавать дополнительные параметры при использовании ORM INSERT с настройкой dml_strategy «orm».

    • Снято требование не передавать дополнительные критерии WHERE при использовании ORM UPDATE с настройкой dml_strategy «bulk». Обратите внимание, что в этом случае отключается проверка на ожидаемое количество строк.

    References: #9583, #9595

  • [orm] [bug]

    Исправлена ошибка версии 2.0, когда использование bindparam() внутри Insert.values() при выполнении оператора Insert с помощью ORM Session не интерпретировалось корректно из-за того, что новый ORM-enabled insert feature не реализовывал этот случай использования.

    References: #9583, #9595

engine

  • [engine] [performance]

    Ряд улучшений производительности Row:

    • Улучшена работа интерфейса «именованный кортеж» строки __getattr__; в рамках этого изменения оптимизирована реализация Row, удалены конструкции и логика, характерные для SQLAlchemy версии 1.4 и более ранних версий. В рамках этого изменения был немного изменен формат сериализации Row, однако строки, которые были замаринованы в предыдущих версиях SQLAlchemy 2.0, будут распознаваться в новом формате. Pull request любезно предоставлен J. Nick Koston.

    • Улучшена производительность обработки строк для «бинарных» типов данных за счет того, что обработчик «bytes» стал условным для каждого драйвера. В результате обработчик результата «bytes» был удален практически для всех драйверов, кроме psycopg2, все из которых в современных формах поддерживают возврат «байтов» Python напрямую. Pull request любезно предоставлен J. Nick Koston.

    • Дополнительные рефакторинги внутри Row для повышения производительности от Федерико Казелли.

    References: #9678, #9680

  • [engine] [bug] [regression]

    Исправлена регрессия, из-за которой не работал атрибут URL.normalized_query в URL.

    References: #9682

sql

  • [sql] [usecase]

    Добавлена поддержка доступа к фрагментам с ColumnCollection, например, table.c[0:5], subquery.c[:-1] и т.д. Доступ к фрагменту возвращает подфрагмент ColumnCollection точно так же, как и передача кортежа ключей. Это естественное продолжение доступа к кортежу ключей, добавленного для #8285, где, по-видимому, по недосмотру был опущен случай использования доступа к срезу.

    References: #8285

typing

  • [typing] [bug]

    Улучшена типизация RowMapping, чтобы указать, что она поддерживает также Column как индексные объекты, а не только строковые имена. Pull request любезно предоставлен Энди Фриландом.

    References: #9644

postgresql

  • [postgresql] [bug] [regression]

    Исправлена критическая регрессия, вызванная функцией #9618, которая изменила архитектуру функции insertmanyvalues для версии 2.0.10, в результате чего значения с плавающей точкой теряли все десятичные знаки при вставке с помощью функции insertmanyvalues в драйверах psycopg2 или psycopg.

    References: #9701

mssql

  • [mssql] [bug]

    Реализован тип Double для SQL Server, где он будет отображать DOUBLE PRECISION во время DDL. Это реализовано с помощью нового MSSQL-типа данных DOUBLE_PRECISION, который также может использоваться напрямую.

oracle

  • [oracle] [bug]

    В диалектах Oracle исправлена проблема, при которой возвращаемые типы Decimal, такие как Numeric, возвращали значения с плавающей точкой, а не объекты Decimal, когда эти столбцы использовались в предложении Insert.returning() для возврата значений INSERTed.

2.0.10

Released: April 21, 2023

orm

  • [orm] [bug]

    Исправлена ошибка, при которой различные ORM-специфичные геттеры, такие как ORMExecuteState.is_column_load, ORMExecuteState.is_relationship_load, ORMExecuteState.loader_strategy_path и т.д., выдавали ошибку AttributeError, если сам SQL-оператор представлял собой «составной select», например, UNION.

    This change is also backported to: 1.4.48

    References: #9634

  • [orm] [bug]

    Исправлена проблема, при которой модификатор declared_attr.directive() некорректно выполнялся для подклассов при применении к имени специального метода __mapper_args__, в отличие от прямого использования declared_attr. Эти две конструкции должны иметь идентичное поведение во время выполнения.

    References: #9625

  • [orm] [bug]

    Внесено усовершенствование в опцию загрузчика with_loader_criteria(), позволяющее указывать ее в методе Executable.options() оператора верхнего уровня, который сам не является ORM-оператором. Примерами могут служить select(), встроенные в составные операторы, такие как union(), внутри конструкции Insert.from_select(), а также в выражениях CTE, которые на верхнем уровне не относятся к ORM.

    References: #9635

  • [orm] [bug]

    Исправлена ошибка в функции массовой вставки ORM, когда при запросе RETURNING отдельных колонок в операторе INSERT выводились дополнительные ненужные колонки.

    References: #9685

  • [orm] [bug]

    Исправлена ошибка в декларативных классах данных ORM, когда конструкции query_expression() и column_property(), которые в контексте декларативного отображения документированы как конструкции только для чтения, не могли быть использованы с классом MappedAsDataclass без добавления init=False, что в случае query_expression() было невозможно, так как не включался параметр init. Эти конструкции были модифицированы с точки зрения класса данных так, чтобы они считались «только для чтения», устанавливая init=False по умолчанию и больше не включая их в конструктор pep-681. Параметры класса данных column_property() init, default, default_factory, kw_only теперь устарели; эти поля не применяются к column_property(), используемым в конфигурации декларативных классов данных, где конструкция будет доступна только для чтения. Также в query_expression() добавлен специфический для чтения параметр query_expression.compare; query_expression.repr уже присутствовал.

    References: #9628

  • [orm] [bug]

    Добавлен недостающий параметр mapped_column.active_history в конструкцию mapped_column().

engine

  • [engine] [usecase]

    Добавлены функции create_pool_from_url() и create_async_pool_from_url() для создания экземпляра Pool из входного url, переданного в виде строки или URL.

    References: #9613

  • [engine] [bug]

    Устранен существенный недостаток, который был выявлен в функции оптимизации производительности Поведение «Вставка многих значений» для операторов INSERT, впервые появившейся в серии 2.0. Это стало продолжением изменения в версии 2.0.9, которое отключило эту функцию в версии для SQL Server из-за того, что ORM полагалась на кажущееся упорядочивание строк, которое не гарантировано. Исправление применяет новую логику ко всем операциям «insertmanyvalues», которая вступает в силу при появлении нового параметра Insert.returning.sort_by_parameter_order в методах Insert.returning() или UpdateBase.return_defaults(), что с помощью комбинации альтернативных форм SQL, прямого соответствия параметрам на стороне клиента и, в некоторых случаях, перехода на выполнение row-at-a-time, позволяет применять сортировку к каждой партии возвращаемых строк, используя соответствие первичному ключу или другим уникальным значениям в каждой строке, которые можно соотнести с входными данными.

    Ожидается, что влияние на производительность будет минимальным, поскольку практически все распространенные сценарии работы с первичными ключами подходят для упорядоченной по параметрам пакетной обработки для всех бэкендов, кроме SQLite, а режим «row-at-a-time» работает с минимальными накладными расходами на Python по сравнению с очень тяжелыми подходами, использовавшимися в серии 1.x. Для SQLite разницы в производительности при использовании режима «row-at-a-time» нет.

    Предполагается, что с помощью эффективного INSERT «row-at-a-time» с возможностью пакетной обработки RETURNING, функция «insertmanyvalues» впоследствии может быть более легко обобщена на сторонние бэкенды, которые включают поддержку RETURNING, но не всегда могут гарантировать соответствие порядку параметров.

    References: #9603, #9618

typing

postgresql

  • [postgresql] [usecase]

    В диалекте asyncpg добавлена опция аргумента соединения prepared_statement_name_func. Данная опция позволяет передать вызываемую переменную, используемую для настройки имени подготовленного оператора, который будет создаваться драйвером при выполнении запросов. Pull request любезно предоставлен Павлом Сироткиным.

    References: #9608

  • [postgresql] [usecase]

    Добавить недостающий метод Range.intersection(). Pull request любезно предоставлен Юрием Карабасом.

    References: #9509

  • [postgresql] [bug]

    Восстановлен необязательный параметр ENUM.name в сигнатуре для ENUM, так как он выбирается автоматически из заданного типа pep-435 Enum.

    References: #9611

  • [postgresql] [bug]

    Исправлена проблема, при которой сравнение для ENUM с обычной строкой приводило к типу правой части VARCHAR, что из-за более явного приведения, добавленного в диалекты, такие как asyncpg, приводило к ошибке несоответствия типов PostgreSQL.

    References: #9621

  • [postgresql] [bug]

    Исправлена проблема, из-за которой в PostgreSQL не удавалось отразить индексы на основе выражений с длинными выражениями. Выражение ошибочно усекалось до длины идентификатора (по умолчанию это 63 байта).

    References: #9615

mssql

  • [mssql] [bug]

    Восстановлена функция insertmanyvalues для Microsoft SQL Server. Эта функция была отключена в версии 2.0.9 из-за очевидной зависимости от порядка RETURNING, который не гарантируется. Архитектура функции «insertmanyvalues» была переработана с учетом специфической организации операторов INSERT и обработки строк результатов, гарантирующей соответствие возвращаемых строк вводимым записям.

    References: #9603, #9618

oracle

  • [oracle] [bug]

    Исправлена проблема, при которой тип данных Uuid не мог быть использован в предложении INSERT..RETURNING в диалекте Oracle.

2.0.9

Released: April 5, 2023

orm

  • [orm] [bug]

    Исправлен бесконечный цикл, который мог возникать при использовании функции «отношение к псевдоклассу», а также при указании в загрузчике рекурсивного ускоренного загрузчика, например lazy="selectinload", в сочетании с другим ускоренным загрузчиком на противоположной стороне. Исправлена проверка на наличие циклов для включения отношений с псевдоклассами.

    This change is also backported to: 1.4.48

    References: #9590

mariadb

  • [mariadb] [bug]

    Добавлено row_number как зарезервированное слово в MariaDb.

    References: #9588

mssql

  • [mssql] [bug]

    Функция SQLAlchemy «insertmanyvalues», обеспечивающая быструю INSERT многих строк и одновременно поддерживающая RETURNING, временно отключена для SQL Server. Поскольку в настоящее время эта функция используется для сопоставления существующих объектов ORM с возвращаемыми идентификаторами первичного ключа, данный шаблон использования не во всех случаях работает с SQL Server, поскольку порядок строк, возвращаемых «OUTPUT inserted», не всегда совпадает с порядком отправки кортежей, что приводит к принятию ORM неверных решений относительно этих объектов в последующих операциях.

    Эта возможность будет вновь включена в ближайшем выпуске и снова будет действовать для многорядных операторов INSERT, однако использование этой возможности в единицах работы будет отключено, возможно, для всех диалектов, если в таблицах, отображаемых на ORM, не будет присутствовать столбец «sentinel», чтобы возвращаемые строки могли быть отнесены к исходным переданным данным.

    References: #9603

  • [mssql] [bug]

    Изменена стратегия массового INSERT, используемая для SQL Server «executemany» с pyodbc при установке fast_executemany в значение True, путем использования fast_executemany / cursor.executemany() для массового INSERT, не включающего RETURNING, восстанавливая то же поведение, которое использовалось в SQLAlchemy 1.4 при установке этого параметра.

    Новые данные о производительности, полученные от конечных пользователей, показали, что fast_executemany по-прежнему значительно быстрее для очень больших наборов данных, поскольку использует команды ODBC, которые могут получать все строки за один цикл, что позволяет использовать гораздо большие объемы данных, чем пакеты, которые могут быть отправлены командой «insertmanyvalues», как это было реализовано для SQL Server.

    Хотя это изменение было сделано таким образом, что «insertmanyvalues» продолжала использоваться для INSERT, включающего RETURNING, а также если fast_executemany не был установлен, из-за #9603, стратегия «insertmanyvalues» была отключена для SQL Server в любом случае.

    References: #9586

2.0.8

Released: March 31, 2023

orm

  • [orm] [usecase]

    Исключения TypeError и ValueError, возникающие в классах данных Python при использовании класса-миксина MappedAsDataclass или декоратора registry.mapped_as_dataclass(), теперь оборачиваются в обертку InvalidRequestError вместе с информационным контекстом сообщения об ошибке, ссылаясь на документацию по классам данных Python как на авторитетный источник справочной информации о причине возникновения исключения.

    References: #9563

  • [orm] [bug]

    Исправлена проблема в ORM Annotated Declarative, когда использование рекурсивного типа (например, использование вложенного типа Dict) приводило к переполнению рекурсии в логике разрешения аннотаций ORM, даже если этот тип данных не был необходим для отображения колонки.

    References: #9553

  • [orm] [bug]

    Исправлена проблема, при которой конструкция mapped_column() вызывала внутреннюю ошибку, если использовалась в декларативном миксине и включала параметр mapped_column.deferred.

    References: #9550

  • [orm] [bug]

    Расширено предупреждение, выдаваемое при наличии в декларативном отображении простого объекта column(), для включения в него произвольного SQL-выражения, не объявленного в соответствующем типе свойств, таких как column_property(), deferred() и т.д. В противном случае эти атрибуты вообще не отображаются и остаются неизменными в словаре класса. Поскольку представляется вероятным, что такое выражение обычно не является тем, что предполагается, в данном случае предупреждение выдается для всех таких игнорируемых выражений, а не только для случая column().

    References: #9537

  • [orm] [bug]

    Исправлена ошибка, при которой обращение к значению выражения гибридного свойства класса, который не был отображен или еще не был отображен (например, обращение к нему в методе declared_attr()), приводило к внутренней ошибке, так как внутренняя выборка для маппера родительского класса не выполнялась, а указание на игнорирование этой ошибки было случайно удалено в 2.0.

    References: #9519

  • [orm] [bug]

    Поля, объявленные в декларативных миксинах и затем объединенные с классами, использующими MappedAsDataclass, где эти поля миксинов сами не являются частью класса данных, теперь выдают предупреждение об устаревании, поскольку в будущем выпуске эти поля будут игнорироваться, так как поведение классов данных Python заключается в игнорировании этих полей. В соответствии с pep-681 программы проверки типов не будут видеть эти поля.

    References: #9350

  • [orm] [bug]

    Исправлена проблема, когда метод BindParameter.render_literal_execute() вызывался с ошибкой при вызове параметра, с которым также связаны аннотации ORM. На практике это проявлялось в виде сбоя компиляции SQL при использовании некоторых комбинаций диалекта, использующего «FETCH FIRST», например, Oracle, и конструкции Select, использующей Select.limit(), в некоторых ORM-контекстах, в том числе, если оператор был встроен в выражение primaryjoin отношения.

    References: #9526

  • [orm] [bug]

    В целях обеспечения согласованности с изменениями в модулях работы, сделанными для #5984 и #8862, которые отключают обработку «lazy=“raise“» в процессах Session, не вызванных доступом к атрибутам, метод Session.delete() теперь также будет отключать обработку «lazy=“raise“» при прохождении путей отношений для обработки каскадных правил «delete» и «delete-orphan». Ранее не существовало простого способа общего вызова Session.delete() на объекте, для которого было установлено «lazy=“raise“» так, чтобы загружались только необходимые отношения. Поскольку «lazy=“raise“» в первую очередь предназначен для отлова SQL-загрузки, возникающей при обращении к атрибутам, Session.delete() теперь ведет себя так же, как и другие методы Session, включая Session.merge(), а также Session.flush() вместе с autoflush.

    References: #9549

  • [orm] [bug]

    Исправлена проблема, при которой в классе Declarative mixin нельзя было использовать директиву Mapped только для аннотаций, при этом атрибут не пытался вступить в силу для подклассов с одиночным или объединенным наследованием сопоставленных классов, которые уже сопоставили этот атрибут суперклассу, что приводило к конфликтующим ошибкам и/или предупреждениям в колонках.

    References: #9564

  • [orm] [bug] [typing]

    Правильно набирать Insert.from_select.names для приема списка строк или столбцов или отображаемых атрибутов.

    References: #9514

examples

  • [examples] [bug]

    Исправлена проблема в примере «история версий», когда использование декларативной базы, производной от DeclarativeBase, не приводило к сопоставлению. Кроме того, исправлен приведенный тестовый набор так, что документированная инструкция по выполнению примера с помощью Python unittest теперь снова работает.

typing

  • [typing] [bug]

    Исправлена типизация для deferred() и query_expression() для корректной работы с отображениями стилей 2.0.

    References: #9536

postgresql

  • [postgresql] [bug]

    Исправлена критическая ошибка в диалектах PostgreSQL, таких как asyncpg, которые полагаются на явные приведения в SQL для корректной передачи типов данных драйверу, когда тип данных String приводился вместе с точной длиной сравниваемого столбца, что приводило к неявному усечению при сравнении VARCHAR меньшей длины со строкой большей длины независимо от используемого оператора (например, LIKE, MATCH и т.д.). Теперь диалект PostgreSQL опускает длину из VARCHAR при приведении.

    References: #9511

mysql

  • [mysql] [bug]

    Исправлена проблема, при которой строковые типы данных, такие как CHAR, VARCHAR, TEXT, а также бинарные BLOB, не могли быть получены с явной длиной, равной нулю, что имеет особое значение для MySQL. Pull request любезно предоставлен J. Nick Koston.

    References: #9544

misc

  • [bug] [util]

    Реализованы недостающие методы copy и pop в классе OrderedSet.

    References: #9487

2.0.7

Released: March 18, 2023

typing

  • [typing] [bug]

    Исправлена проблема типизации, при которой composite() не позволял использовать произвольный вызываемый класс в качестве источника составного класса.

    References: #9502

postgresql

  • [postgresql] [usecase]

    Добавлен новый тип PostgreSQL CITEXT. Pull request любезно предоставлен Джулианом Дэвидом Ратом.

    References: #9416

  • [postgresql] [usecase]

    Изменения в базовом диалекте PostgreSQL для лучшей интеграции со сторонним диалектом sqlalchemy-redshift для SQLAlchemy 2.0. Pull request courtesy matthewgdv.

    References: #9442

2.0.6

Released: March 13, 2023

orm

  • [orm] [bug]

    Исправлена ошибка, при которой функция «активная история» не была полностью реализована для составных атрибутов, что делало невозможным получение событий, включающих «старое» значение. По-видимому, это происходило и в старых версиях SQLAlchemy, когда «active_history» распространялась на базовые атрибуты, основанные на столбцах, но обработчик событий, прослушивающий сам составной атрибут, не получал заменяемое «старое» значение, даже если в composite() было установлено значение active_history=True.

    Кроме того, исправлена локальная для 2.0 регрессия, из-за которой active_history в композите не присваивалась импу с помощью attr.impl.active_history=True.

    References: #9460

  • [orm] [bug]

    Исправлена регрессия, связанная с замариванием строк Python между cython- и чисто Python-реализациями Row, которая возникла в ходе рефакторинга кода для версии 2.0 с типизацией. Определенная константа превращалась в строковую Enum для чистой Python-версии Row, в то время как в cython-версии продолжала использоваться целочисленная константа, что приводило к сбоям десериализации.

    References: #9418

sql

  • [sql] [bug] [regression]

    Исправлена регрессия, когда исправление для #8098, выпущенное в серии 1.4 и обеспечивающее уровень concurrency-safe проверок для лямбда SQL API, включало дополнительные исправления в патче, которые не удалось применить к основной ветке. Эти дополнительные исправления были применены.

    References: #9461

  • [sql] [bug]

    Исправлена ошибка, при которой конструкция select() не могла быть выведена на экран, если она не имела столбцов, а затем использовалась в контексте EXISTS, вызывая внутреннее исключение. Хотя пустой «SELECT» обычно не является корректным SQL, в контексте EXISTS такие базы данных, как PostgreSQL, допускают его, и в любом случае условие теперь не вызывает внутреннего исключения.

    References: #9440

typing

  • [typing] [bug]

    Исправлена проблема типизации, при которой ColumnElement.cast() не допускал аргумента TypeEngine, не зависящего от типа самого ColumnElement, что является целью ColumnElement.cast().

    References: #9451

  • [typing] [bug]

    Исправлены проблемы, позволяющие проходить тесты типизации под Mypy 1.1.1.

oracle

  • [oracle] [bug]

    Исправлена ошибка отражения, при которой Oracle «name normalize» не работал корректно при отражении символов, находящихся в схеме «PUBLIC», таких как синонимы, в результате чего имя PUBLIC не могло быть указано в нижнем регистре на стороне Python для аргумента Table.schema. Использование заглавной буквы «PUBLIC» работало, но при этом приводило к неудобным SQL-запросам, включающим заключенное в кавычки имя "PUBLIC", а также к индексированию таблицы по заглавной букве «PUBLIC», что было непоследовательно.

    References: #9459

2.0.5.post1

Released: March 5, 2023

orm

  • [orm] [bug]

    Добавлены аргументы конструктора для встроенных типов коллекций отображений, включая KeyFuncDict, attribute_keyed_dict(), column_keyed_dict(), чтобы эти словарные типы можно было конструировать на месте, предварительно задав данные; это обеспечивает дополнительную совместимость с такими инструментами, как Python dataclasses .asdict(), которые полагаются на обращение к этим классам непосредственно как к обычным классам словарей.

    References: #9418

  • [orm] [bug] [regression]

    Исправлены многочисленные регрессии, связанные с #8372, включающие attribute_mapped_collection() (теперь называется attribute_keyed_dict()).

    Во-первых, коллекция перестала работать с «ключевыми» атрибутами, которые сами не являлись обычными отображаемыми атрибутами; исправлены атрибуты, связанные с дескрипторами и/или прокси-атрибутами ассоциаций.

    Во-вторых, если событию или другой операции требовался доступ к «ключу» для заполнения словаря из сопоставленного атрибута, который не был загружен, то это также приводило к ошибке, а не к попытке загрузить атрибут, как это было в 1.4. Это также исправлено.

    Для обоих случаев поведение #8372 было расширено. В #8372 была введена ошибка, возникающая в том случае, если производный ключ, который будет использоваться в качестве ключа сопоставленного словаря, фактически не назначен. В данном изменении предупреждение выдается только в том случае, если эффективное значение атрибута «.key» равно None, когда нельзя однозначно определить, было ли это None намеренным или нет. В дальнейшем None не будет поддерживаться в качестве ключей словарей сопоставленных коллекций (так как обычно ссылается на NULL, что означает «неизвестно»). Установка attribute_keyed_dict.ignore_unpopulated_attribute теперь будет приводить к тому, что такие ключи None также будут игнорироваться.

    References: #9424

  • [orm] [bug]

    Установлено, что диалекты sqlite и mssql+pyodbc теперь совместимы с функцией «версионированные строки» SQLAlchemy ORM, поскольку SQLAlchemy теперь вычисляет rowcount для оператора RETURNING в этом конкретном случае путем подсчета возвращаемых строк, а не полагаясь на cursor.rowcount. В частности, вариант использования ORM versioned rows (документированный в Настройка счетчика версий) теперь должен полностью поддерживаться диалектом SQL Server pyodbc.

  • [orm] [bug]

    Добавлена поддержка применения параметра Mapper.polymorphic_load к каждому отображателю в иерархии наследования глубиной более одного уровня, что позволяет загружать колонки для всех классов иерархии, указывающих на "selectin", с помощью одного оператора, а не игнорировать элементы промежуточных классов, которые, тем не менее, указывают на то, что они также будут участвовать в загрузке "selectin" и не являются частью самого базового оператора SELECT.

    References: #9373

  • [orm] [bug]

    Продолжено исправление для #8853, позволяющее имени Mapped быть полностью квалифицированным независимо от наличия или отсутствия from __annotations__ import future. Эта проблема, впервые исправленная в версии 2.0.0b3, подтвердила работоспособность данного случая через набор тестов, однако набор тестов, очевидно, не проверял поведение для имени Mapped вообще не присутствующего локально; разрешение строк было обновлено для обеспечения локальности символа Mapped, что относится к тому, как ORM использует эти функции.

    References: #8853, #9335

orm declarative

  • [bug] [orm declarative]

    Исправлена проблема, при которой новый параметр mapped_column.use_existing_column не работал, если два одноименных столбца были отображены под именами атрибутов, которые отличались от явного имени, заданного самому столбцу. Теперь при использовании этого параметра имена атрибутов могут быть разными.

    References: #9332

engine

  • [engine] [performance]

    Небольшая оптимизация реализации Result в Cython, использующая cdef для конкретного значения int, чтобы избежать накладных расходов на Python. Pull request любезно предоставлен Матусом Вало.

    References: #9343

  • [engine] [bug]

    Исправлена ошибка, при которой объекты Row не могли надежно распаковываться между процессами из-за случайного использования нестабильного хэш-значения.

    References: #9423

sql

  • [sql] [bug] [regression]

    Восстановление старых функций nullslast() и nullsfirst() в пространстве имен импорта sqlalchemy. Ранее новые функции nulls_last() и nulls_first() были доступны, а старые были непреднамеренно удалены.

    References: #9390

schema

  • [schema]

    Убедиться, что при предоставлении аргумента MetaData.schema аргумент MetaData является строкой.

typing

  • [typing] [usecase]

    Экспорт типа, возвращаемого scoped_session.query_property(), с использованием нового публичного типа QueryPropertyDescriptor.

    References: #9338

  • [typing] [bug]

    Исправлена ошибка, при которой метод Connection.scalars() не типизировался как позволяющий создавать список с несколькими параметрами, что теперь поддерживается с помощью операций insertmanyvalues.

  • [typing] [bug]

    Улучшена типизация отображения, передаваемого в Insert.values() и Update.values(), для более свободного выбора типа коллекции: вместо Writeable Dict указывается read-only Mapping, что приводит к ошибке при слишком ограниченном типе ключа.

    References: #9376

  • [typing] [bug]

    Добавлена недостающая перегрузка init для объекта типа Numeric, чтобы программы проверки типов pep-484 могли правильно определять полный тип, определяя по параметру Numeric.asdecimal, будут ли представлены объекты Decimal или float.

    References: #9391

  • [typing] [bug]

    Исправлена ошибка типизации, при которой Select.from_statement() не принимал в качестве допустимого типа объекты text() или TextualSelect. Дополнительно исправлен тип возврата метода columns, который отсутствовал.

    References: #9398

  • [typing] [bug]

    Исправлена проблема ввода, при которой with_polymorphic() не записывал корректно тип класса.

    References: #9340

postgresql

  • [postgresql] [bug]

    Исправлена проблема в PostgreSQL ExcludeConstraint, когда литеральные значения компилировались как связанные параметры, а не как прямые инлайн-значения, как это требуется для DDL.

    References: #9349

  • [postgresql] [bug]

    Исправлена проблема, при которой конструкция PostgreSQL ExcludeConstraint не копировалась в операциях типа Table.to_metadata(), а также в некоторых сценариях Alembic, если ограничение содержало элементы текстового выражения.

    References: #9401

mysql

  • [mysql] [bug] [postgresql]

    Поддержка пула ping-слушателей для получения событий исключений через событие DialectEvents.handle_error(), добавленная в 2.0.0b1 для #5648, не учитывала специфические для диалектов ping-процедуры, такие как MySQL и PostgreSQL. Функция диалектов была переработана таким образом, чтобы все диалекты участвовали в обработке событий. Кроме того, добавлен новый булевский элемент ExceptionContext.is_pre_ping, который определяет, выполняется ли данная операция в рамках предварительного пинга.

    В этом выпуске сторонние диалекты, реализующие пользовательский метод Dialect.do_ping(), могут перейти на новое улучшенное поведение: их метод больше не будет перехватывать исключения или проверять исключения на «is_disconnect», а просто будет распространять все исключения наружу. Проверка исключения на «is_disconnect» теперь выполняется с помощью вложенного метода в диалекте по умолчанию, который гарантирует, что крючок событий будет вызван для всех сценариев исключений, прежде чем проверить исключение как исключение «disconnect». Если существующий метод do_ping() продолжает перехватывать исключения и проверять «is_disconnect», он будет продолжать работать, как и раньше, но крючки handle_error не будут иметь доступа к исключению, если оно не будет распространено наружу.

    References: #5648

sqlite

  • [sqlite] [bug] [regression]

    Исправлена регрессия для соединений SQLite, когда использование параметра deterministic при создании функций базы данных приводило к ошибке для старых версий SQLite, предшествующих версии 3.8.3. Для этого случая была улучшена логика проверки версии.

    References: #9379

mssql

  • [mssql] [bug]

    Исправлена проблема в новом типе данных Uuid, из-за которой он не работал с драйвером pymssql. Поскольку pymssql, похоже, снова поддерживается, восстановлено тестирование поддержки pymssql.

    References: #9414

  • [mssql] [bug]

    Настроен диалект pymssql, чтобы лучше использовать RETURNING для операторов INSERT для получения последних вставленных значений первичного ключа, аналогично тому, как это происходит в диалекте mssql+pyodbc в настоящее время.

misc

  • [bug] [ext]

    Исправлена проблема в automap, когда вызов AutomapBase.prepare() из определенного сопоставленного класса, а не из AutomapBase напрямую, не использовал правильный базовый класс при обнаружении новых таблиц, а использовал заданный класс, что приводило к попыткам мапперов настроить наследование. Хотя, как правило, в любом случае следует вызывать AutomapBase.prepare() из базы, она не должна так плохо вести себя при вызове из подкласса.

    References: #9367

  • [bug] [ext] [regression]

    Исправлена регрессия, вызванная добавлением в sqlalchemy.ext.mutable типизации для #8667, при которой семантика метода .pop() изменялась таким образом, что метод становился нерабочим. Pull request любезно предоставлен Nils Philippsen.

    References: #9380

2.0.4

Released: February 17, 2023

orm

  • [orm] [usecase]

    Для адаптации изменения порядка следования столбцов, используемого ORM Declarative в SQLAlchemy 2.0, был добавлен новый параметр mapped_column.sort_order, который может быть использован для управления порядком следования столбцов, определенных в таблице ORM, для таких распространенных случаев использования, как миксины с первичными ключевыми столбцами, которые должны появляться первыми в таблицах. Примечания к изменениям в Декларативный ORM применяет порядок столбцов по-разному; управление поведением с помощью sort_order иллюстрируют изменение порядка по умолчанию (которое является частью всех релизов SQLAlchemy 2.0), а также использование mapped_column.sort_order для управления порядком колонок при использовании миксинов и нескольких классов (новое в 2.0.4).

    References: #9297

  • [orm] [usecase]

    Метод Session.refresh() теперь будет немедленно загружать связанный с отношениями атрибут, явно названный в коллекции Session.refresh.attribute_names, даже если он в данный момент связан с загрузчиком «select», который обычно является «ленивым» загрузчиком, не срабатывающим при обновлении. Теперь стратегия «ленивого загрузчика» будет определять, что операция Session.refresh(), инициированная пользователем, явно именует этот атрибут, и будет вызывать стратегию «немедленной загрузки» для выполнения SQL-запроса на загрузку атрибута. Это может быть полезно, в частности, для некоторых ситуаций в asyncio, когда необходимо принудительно загрузить незагруженный атрибут lazy-loaded, без использования собственно шаблона lazy-loading, не поддерживаемого в asyncio.

    References: #9298

  • [orm] [bug] [regression]

    Исправлена регрессия, появившаяся в версии 2.0.2 из-за #9217, когда использование операторов DML RETURNING, а также конструкций Select.from_statement(), как это было «исправлено» в #9217, в сочетании с ORM mapped классами, использующими выражения, например, column_property(), приводило к внутренней ошибке в Core, когда он пытался сопоставить выражение по имени. Данное исправление устраняет проблему в Core, а также корректирует исправление в #9217 так, чтобы оно не действовало для случая использования DML RETURNING, где оно добавляет ненужные накладные расходы.

    References: #9273

  • [orm] [bug]

    Пометили внутренний модуль EvaluatorCompiler как приватный для ORM и переименовали его в _EvaluatorCompiler. Для пользователей, которые могли полагаться на это, имя EvaluatorCompiler по-прежнему присутствует, однако его использование не поддерживается и будет удалено в будущем выпуске.

orm declarative

  • [usecase] [orm declarative]

    Добавлен новый параметр dataclasses_callable как в класс MappedAsDataclass, так и в метод registry.mapped_as_dataclass(), который позволяет использовать для создания классов данных альтернативный вызов Python dataclasses.dataclass. В данном случае вместо него используется функция Pydantic для создания dataclass. В версию 2.0.1 была внесена корректировка в поддержку миксинов, добавленных для #9179, так что коллекция __annotations__ миксина переписана так, чтобы не включать контейнер Mapped, подобно тому, как это происходит с отображаемыми классами, чтобы конструктор Pydantic dataclasses не подвергался воздействию неизвестных типов.

    References: #9266

sql

  • [sql] [bug]

    Исправлена проблема, при которой типы элементов кортежа-значения жестко кодировались так, чтобы принимать типы из сравниваемого кортежа, когда для сравнения использовался оператор ColumnOperators.in_(). Это не соответствовало обычному способу определения типов для бинарных выражений, согласно которому сначала рассматривается тип элемента в правой части, а затем применяется тип в левой части.

    References: #9313

  • [sql]

    Добавлено публичное свойство Table.autoincrement_column, возвращающее столбец, идентифицированный как автоинкрементный в столбце.

    References: #9277

typing

  • [typing] [usecase]

    Улучшена поддержка типизации для расширения Атрибуты гибрида, обновлена вся документация для использования ORM Annotated Declarative mappings, добавлен новый модификатор hybrid_property.inplace. Этот модификатор позволяет изменять состояние hybrid_property на месте, что, по сути, и делали ранние версии гибридов, пока в SQLAlchemy версии 1.2.0 #3912 не было изменено на удаление мутации на месте. Теперь мутация на месте восстанавливается на основе opt-in, чтобы позволить одному гибриду иметь несколько методов, без необходимости называть все методы одинаково и без необходимости тщательно «выстраивать цепочки» методов с разными именами для сохранения композиции. Такие инструменты типизации, как Mypy и Pyright, не позволяют использовать одноименные методы в классе, поэтому с помощью данного изменения восстанавливается простой способ создания гибридов с поддержкой типизации.

    References: #9321

oracle

  • [oracle] [bug]

    Скорректировано поведение параметра thick_mode для диалекта python-oracledb, чтобы он корректно принимал значение False. Ранее только None указывал на то, что толстый режим должен быть отключен.

    References: #9295

2.0.3

Released: February 9, 2023

sql

  • [sql] [bug] [regression]

    Исправлена критическая ошибка в формулировке SQL-выражений в серии 2.0, связанная с использованием #7744, что улучшило поддержку SQL-выражений, содержащих множество элементов против одного и того же оператора многократно; группировка скобок терялась при использовании элементов выражения, выходящих за пределы первых двух элементов.

    References: #9271

typing

  • [typing] [bug]

    Устранено обходное решение typing.Self, теперь для большинства методов, возвращающих Self, используется PEP 673. Вследствие этого изменения для проверки типа кода SQLAlchemy теперь требуется mypy>=1.0.0. Pull request любезно предоставлен Юрием Карабасом.

    References: #9254

2.0.2

Released: February 6, 2023

orm

  • [orm] [usecase]

    Добавлен новый крючок событий MapperEvents.after_mapper_constructed(), который предоставляет крючок событий, происходящих сразу после полного построения объекта Mapper, но до вызова registry.configure(). Это позволяет коду создавать дополнительные отображения и структуры таблиц на основе начальной конфигурации Mapper, что также интегрируется в конфигурацию Declarative. Ранее при использовании Declarative, где объект Mapper создается в процессе создания класса, не существовало документированных средств для запуска кода в этот момент. Это изменение сразу же должно принести пользу пользовательским схемам отображения, таким как в примере Версионирование с помощью таблицы истории, которые генерируют дополнительные отображатели и таблицы в ответ на создание отображаемых классов.

    References: #9220

  • [orm] [usecase]

    Редко используемые атрибут Mapper.iterate_properties и метод Mapper.get_property(), которые в основном используются внутри компании, больше не вызывают неявно процесс registry.configure(). Публичный доступ к этим методам осуществляется крайне редко, и единственным преимуществом наличия registry.configure() было бы разрешение на присутствие в этих коллекциях свойств «обратной ссылки». Для поддержки нового события MapperEvents.after_mapper_constructed() итерация и доступ к внутренним объектам MapperProperty теперь возможны без инициирования неявной конфигурации самого отображателя.

    Более публичный путь к итерации всех атрибутов отображения, коллекция Mapper.attrs и подобные ей, по-прежнему будет неявно вызывать шаг registry.configure(), делая доступными атрибуты backref.

    Во всех случаях registry.configure() всегда доступен для прямого вызова.

    References: #9220

  • [orm] [bug] [ression]

    Исправлена неясная проблема наследования ORM, вызванная #8705, когда в некоторых сценариях наследования отображателей, указывающих под column_property() группы колонок из локальной таблицы и наследуемой таблицы вместе, тем не менее, выдавалось предупреждение о неявном объединении одноименных свойств.

    References: #9232

  • [orm] [bug] [regression]

    Исправлена ошибка, при которой использование функции Mapper.version_id_col с обычным инкрементирующим столбцом на стороне Python не работало для SQLite и других баз данных, не поддерживающих «rowcount» с «RETURNING», поскольку для таких столбцов предполагалось «RETURNING», хотя на самом деле этого не происходило.

    References: #9228

  • [orm] [bug] [regression]

    Исправлена регрессия при использовании Select.from_statement() в контексте ORM, когда для ORM-выражений, не являющихся полностью текстовыми, было запрещено сопоставление столбцов с SQL-метками, основанными только на имени. Это приводило к тому, что произвольные SQL-выражения с метками в виде имен столбцов не могли соответствовать загружаемой сущности, что ранее работало в версии 1.4 и предыдущих, поэтому прежнее поведение восстановлено.

    References: #9217

orm declarative

  • [bug] [orm declarative]

    Исправлена регрессия, вызванная исправлением #9171, которое само по себе исправляло регрессию, связанную с механикой применения __init__() к классам, расширяемым из DeclarativeBase. Это изменение приводило к тому, что __init__() применялся к пользовательской базе, если непосредственно в классе не было метода __init__(). Это было исправлено таким образом, что __init__() применяется только в том случае, если ни один другой класс в иерархии определяемой пользователем базы не имеет метода __init__(). Это снова позволяет определяемым пользователем базовым классам, основанным на DeclarativeBase, включать в себя миксины, которые сами включают в себя пользовательский метод __init__().

    References: #9249

  • [bug] [orm declarative]

    Исправлена проблема в отображениях декларативных классов данных ORM, связанная с добавленной в 2.0.1 поддержкой миксинов через #9179, когда сочетание использования миксинов и наследования ORM в некоторых случаях неправильно классифицировало поля, что приводило к потере аргументов класса данных на уровне полей, таких как init=False.

    References: #9226

  • [bug] [orm declarative]

    Исправлены декларативные связки ORM, позволяющие указывать параметр Mapper.primary_key внутри __mapper_args__ при использовании mapped_column(). Несмотря на то, что этот вариант использования был прямо указан в документации 2.0, Mapper не принимал конструкцию mapped_column() в этом контексте. Эта возможность уже работала для параметров Mapper.version_id_col и Mapper.polymorphic_on.

    В рамках этого изменения атрибут __mapper_args__ может быть указан без использования declared_attr() на не маппированном классе mixin, включая запись "primary_key", которая ссылается на объекты Column или mapped_column(), локально присутствующие на mixin; Declarative также переведет эти колонки в правильные для конкретного маппированного класса. Это уже работало для параметров Mapper.version_id_col и Mapper.polymorphic_on. Кроме того, элементы внутри "primary_key" могут быть указаны как строковые имена существующих маппируемых свойств.

    References: #9240

  • [bug] [orm declarative]

    При попытке совмещения использования MappedAsDataclass и registry.mapped_as_dataclass() в рамках одной иерархии классов возникает явная ошибка, поскольку в этом случае функция класса данных применяется к отображаемому классу в неправильное время, что приводит к ошибкам в процессе отображения.

    References: #9211

examples

sql

  • [sql] [usecase]

    Добавлен полный набор новых побитовых операторов SQL для выполнения побитовых выражений на стороне базы данных над соответствующими значениями данных, такими как целые числа, битовые строки и т.п. Pull request любезно предоставлен Егором Статкевичем.

    References: #8780

asyncio

  • [asyncio] [bug]

    Исправлена регрессия, вызванная исправлением #8419, которая приводила к сбросу asyncpg-соединений (т.е. вызову транзакции rollback()) и их нормальному возврату в пул в случае, когда соединение не было явно возвращено в пул соединений, а вместо этого перехватывалось сборщиком мусора Python, что при вызове операции сборки мусора вне цикла событий asyncio приводило к большому количеству трассировки стека, выводимой в лог и стандартный вывод.

    Восстановлено корректное поведение, при котором все asyncio-соединения, которые собираются в мусор из-за того, что не были явно возвращены в пул соединений, отделяются от пула и отбрасываются с предупреждением, а не возвращаются в пул, поскольку их невозможно надежно сбросить. В случае asyncpg-соединений будет использоваться специфический для asyncpg-соединений метод terminate() для более изящного завершения соединения в рамках этого процесса, а не просто для его сброса.

    Это изменение включает в себя небольшое изменение поведения, которое, как ожидается, будет полезно для отладки asyncio-приложений. Предупреждение, выдаваемое в случае неожиданной сборки мусора в asyncio-соединениях, стало немного агрессивнее за счет переноса его за пределы блока try/except и в блок finally:, где оно будет выдаваться безусловно, независимо от того, удалась операция отсоединения/завершения или нет. Это также приведет к тому, что приложения и тестовые пакеты, которые переводят предупреждения Python в исключения, будут воспринимать это как полное повышение исключения, в то время как ранее было невозможно, чтобы это предупреждение распространялось как исключение. Приложениям и тестовым пакетам, которым необходимо терпеть это предупреждение в промежуточный период, следует настроить фильтр предупреждений Python таким образом, чтобы эти предупреждения не поднимались.

    Поведение традиционных синхронных соединений остается неизменным: соединения, собранные в пул, продолжают нормально возвращаться в пул без выдачи предупреждения. Вероятно, в будущем мажорном выпуске это будет изменено, чтобы, по крайней мере, выдавалось предупреждение, аналогичное тому, что выдается для драйверов asyncio, поскольку перехват собранных в пул соединений сборщиком мусора без их корректного возврата в пул является ошибкой использования.

    References: #9237

mysql

  • [mysql] [bug] [regression]

    Исправлена регрессия, вызванная выпуском #9058, в котором диалект MySQL has_table() был настроен на повторное использование «DESCRIBE», где специфический код ошибки, выдаваемый MySQL версии 8 при использовании несуществующего имени схемы, был неожиданным и не мог быть интерпретирован как булевский результат.

    References: #9251

  • [mysql] [bug]

    Добавлена поддержка нового синтаксиса MySQL 8 AS <name> ON DUPLICATE KEY при использовании Insert.on_duplicate_key_update(), который необходим для новых версий MySQL 8, поскольку прежний синтаксис VALUES() в этих версиях выдает предупреждение об устаревании. Определение версии сервера используется для определения того, следует ли использовать традиционный синтаксис MariaDB / MySQL <8 VALUES(), а не более новый синтаксис, требуемый MySQL 8. Pull request любезно предоставлен Caspar Wylie.

    References: #8626

sqlite

  • [sqlite] [bug]

    Исправлена функция has_table() диалекта SQLite, которая корректно сообщает False для запросов, включающих имя схемы не None для несуществующей схемы; ранее выдавалась ошибка базы данных.

    References: #9251

2.0.1

Released: February 1, 2023

orm

  • [orm] [bug] [regression]

    Исправлена ошибка, при которой в ORM-моделях, использующих наследование объединенных таблиц с составным внешним ключом, возникала внутренняя ошибка во внутреннем устройстве mapper.

    References: #9164

  • [orm] [bug]

    Улучшено сообщение об ошибке при связывании опций стратегии из базового класса с другим атрибутом, находящимся вне подкласса, где следует использовать of_type(). Ранее при использовании Load.options() в сообщении отсутствовала информативная информация о том, что следует использовать of_type(), чего не происходило при непосредственном связывании опций. Теперь информационная информация выдается даже при использовании Load.options().

    References: #9182

orm declarative

  • [bug] [orm declarative]

    Добавлена поддержка PEP 484 NewType для использования в registry.type_annotation_map, а также внутри конструкций Mapped. Эти типы будут вести себя так же, как сейчас пользовательские подклассы типов; они должны явно появляться в registry.type_annotation_map, чтобы быть отображенными.

    References: #9175

  • [bug] [orm declarative]

    При использовании суперкласса MappedAsDataclass все классы в иерархии, являющиеся подклассами этого класса, теперь будут проходить через функцию @dataclasses.dataclass независимо от того, отображены они или нет, так что при превращении отображенных подклассов в классы данных будут использоваться поля не-ORM, объявленные в не отображенных классах иерархии. Это поведение распространяется как на промежуточные классы, отображаемые с помощью __abstract__ = True, так и на саму пользовательскую декларативную базу, при условии, что MappedAsDataclass присутствует в качестве суперкласса для этих классов.

    Это позволяет использовать не отображаемые атрибуты, такие как объявления InitVar в суперклассах, без необходимости явного запуска декоратора @dataclasses.dataclass для каждого не отображаемого класса. Новое поведение считается корректным, поскольку именно этого ожидает реализация PEP 681 при использовании суперкласса для указания поведения класса данных.

    References: #9179

  • [bug] [orm declarative]

    Добавлена поддержка PEP 586 Literal[] для использования в registry.type_annotation_map, а также внутри конструкций Mapped. Для использования пользовательских типов, таких как эти, они должны явно присутствовать в registry.type_annotation_map, которые будут сопоставлены. Pull request любезно предоставлен Фредериком Аалундом.

    В рамках этого изменения поддержка Enum в registry.type_annotation_map была расширена, и в дополнение к типам данных была добавлена поддержка Literal[] типов, состоящих из строковых значений, которые будут использоваться в дополнение к enum.Enum типам данных. Если внутри Mapped[] используется Literal[] тип данных, не связанный в registry.type_annotation_map с конкретным типом данных, то по умолчанию будет использоваться Enum.

    References: #9187

  • [bug] [orm declarative]

    Исправлена проблема, связанная с использованием Enum внутри registry.type_annotation_map, когда параметр Enum.native_enum некорректно копировался в сопоставленный тип данных столбца, если переопределить, как указано в документации, значение этого параметра на False.

    References: #9200

  • [bug] [orm declarative] [regression]

    Исправлена ошибка в классе DeclarativeBase, когда конструктор реестра по умолчанию не применялся к самой базе, что отличается от работы предыдущей конструкции declarative_base(). Это не позволяло сопоставленному классу с собственным методом __init__() вызывать super().__init__() для доступа к конструктору по умолчанию реестра и автоматического заполнения атрибутов, а вместо этого вызывать object.__init__(), что приводило к появлению TypeError при любых аргументах.

    References: #9171

  • [bug] [orm declarative]

    Улучшен набор правил для интерпретации типов PEP 593 Annotated при использовании аннотированного декларативного отображения, внутренний тип будет проверяться на «Optional» во всех случаях, что будет добавлено к критерию, по которому столбец устанавливается как «nullable» или нет; если тип внутри контейнера Annotated является опциональным (или объединенным с None), столбец будет считаться nullable, если нет явных mapped_column.nullable параметров, переопределяющих его.

    References: #9177

sql

  • [sql] [bug]

    Исправление для #7664, выпущенное в версии 2.0.0, включает также DropSchema, который был случайно пропущен в этом исправлении, что позволяет выполнять стрингтификацию без диалекта. Исправления для обеих конструкций перенесены в серию 1.4 начиная с версии 1.4.47.

    References: #7664

  • [sql] [bug] [regression]

    Исправлена регрессия, связанная с реализацией новой функции «insertmanyvalues», когда внутренняя TypeError возникала в схемах, где insert() ссылался на внутри другого insert() через CTE; сделаны дополнительные исправления для этого случая использования позиционных диалектов, таких как asyncpg, при использовании «insertmanyvalues».

    References: #9173

typing

  • [typing] [bug]

    Открыл возможность вводить в Select.with_for_update.of также аргументы table и mapped class, как это, по-видимому, доступно для диалекта MySQL.

    References: #9174

  • [typing] [bug]

    Исправлена типизация методов ограничения/смещения, включая Select.limit(), Select.offset(), Query.limit(), Query.offset(), чтобы разрешить None, который является документированным API для «отмены» текущего ограничения/смещения.

    References: #9183

  • [typing] [bug]

    Исправлена проблема типизации, при которой объекты mapped_column(), типизированные как Mapped, не принимались в ограничениях схемы, таких как ForeignKey, UniqueConstraint или Index.

    References: #9170

  • [typing] [bug]

    Исправлена типизация ColumnElement.cast() для принятия Type[TypeEngine[T]] и TypeEngine[T]; ранее принималось только TypeEngine[T]. Pull request любезно предоставлен Юрием Карабасом.

    References: #9156

2.0.0

Released: January 26, 2023

orm

  • [orm] [bug]

    Улучшено уведомление о предупреждениях, выдаваемых в процессе configure mappers или flush, которые часто вызываются как часть другой операции, для добавления дополнительного контекста к сообщению, указывающего на одну из этих операций как источник предупреждения в рамках операций, которые могут быть неочевидно связаны.

    References: #7305

orm extensions

  • [feature] [orm extensions]

    В API горизонтального шардинга добавлена новая опция set_shard_id, устанавливающая эффективный идентификатор шарда для запроса, как для первичного запроса, так и для всех вторичных загрузчиков, включая загрузчики с нетерпеливой загрузкой отношений, а также загрузчики с нетерпеливой загрузкой отношений и столбцов.

    References: #7226

  • [usecase] [orm extensions]

    В AutomapBase добавлена возможность автозагрузки классов по нескольким схемам, имена которых могут пересекаться, с помощью параметра AutomapBase.prepare.modulename_for_table, позволяющего настраивать атрибут __module__ вновь создаваемых классов, а также новой коллекции AutomapBase.by_module, хранящей разделенное точками пространство имен модулей, связанных с классами на основе атрибута __module__.

    Кроме того, метод AutomapBase.prepare() теперь может быть вызван любое количество раз, как с включенным отражением, так и без него; при каждом вызове будут обрабатываться только вновь добавленные таблицы, которые ранее не были отображены. Ранее метод MetaData.reflect() необходимо было каждый раз вызывать явно.

    См.также

    Генерация отображений из нескольких схем - иллюстрирует использование сразу двух техник.

    References: #5145

sql

  • [sql] [bug]

    Исправлена ошибка stringify для DDL-конструкции CreateSchema, которая при строке без диалекта выдавала ошибку AttributeError. Обновление: Обратите внимание, что это исправление не учитывало DropSchema; последующее исправление в версии 2.0.1 исправляет этот случай. Исправление для обоих элементов перенесено в версию 1.4.47.

    References: #7664

typing

  • [typing] [bug]

    Добавлена типизация для встроенных общих функций, доступных из пространства имен func, которые принимают определенный набор аргументов и возвращают определенный тип, например, для count, current_timestamp и т.д.

    References: #9129

  • [typing] [bug]

    Исправлен тип, передаваемый для «лямбда-операторов», так что обычная лямбда принимается mypy, pyright и другими без ошибок о типах аргументов. Дополнительно реализована типизация большей части публичного API для лямбда-операторов и обеспечена принадлежность StatementLambdaElement к иерархии Executable, чтобы он типизировался как принимаемый Connection.execute().

    References: #9120

  • [typing] [bug]

    Методы ColumnOperators.in_() и ColumnOperators.not_in() типизированы и включают в себя Iterable[Any], а не Sequence[Any] для большей гибкости в выборе типа аргумента.

    References: #9122

  • [typing] [bug]

    Функции or_() и and_() с точки зрения типизации требуют наличия первого аргумента, однако эти функции по-прежнему принимают нулевые аргументы, о чем во время выполнения будет выдано предупреждение об устаревании. Также добавлена поддержка передачи фиксированного литерала False для or_() и True для and_() только в качестве первого аргумента, однако в документации теперь указывается, что в этих случаях в качестве более явного подхода следует передавать конструкции false() и true().

    References: #9123

  • [typing] [bug]

    Исправлена проблема типизации, когда итерация над объектом Query была некорректной.

    References: #9125

  • [typing] [bug]

    Исправлена проблема, при которой тип объекта при использовании Result в качестве менеджера контекста не сохранялся, указывая во всех случаях Result, а не конкретный подтип Result. Pull request любезно предоставлен Martin Baláž.

    References: #9136

  • [typing] [bug]

    Исправлена проблема, при которой использование параметра relationship.remote_side и подобных ему, передавая аннотированный декларативный объект, типизированный как Mapped, не принималось программой проверки типов.

    References: #9150

  • [typing] [bug]

    Добавлена типизация для старых операторов, таких как isnot(), notin_() и т.д., которые ранее ссылались на новые операторы, но сами не были типизированы.

    References: #9148

postgresql

  • [postgresql] [bug]

    В диалект asyncpg добавлена поддержка возврата значения cursor.rowcount для операторов SELECT, если оно доступно. Хотя это не является типичным использованием cursor.rowcount, другие диалекты PostgreSQL обычно предоставляют это значение. Pull request любезно предоставлен Майклом Горвеном.

    This change is also backported to: 1.4.47

    References: #9048

mysql

  • [mysql] [usecase]

    Добавлена поддержка отражения индексов MySQL для корректного отражения словаря mysql_length, который ранее игнорировался.

    This change is also backported to: 1.4.47

    References: #9047

mssql

  • [mssql] [bug] [regression]

    Новая возможность отражения и отображения комментариев в диалекте MSSQL, добавленная в #7844, теперь будет отключена по умолчанию, если не удастся определить, что используется неподдерживаемый бэкенд, например Azure Synapse; этот бэкенд не поддерживает комментарии к таблицам и столбцам и не поддерживает процедуры SQL Server, используемые для их генерации и отражения. В диалект добавлен новый параметр supports_comments, который по умолчанию имеет значение None, указывающее на то, что поддержка комментариев должна определяться автоматически. При установке значения True или False поддержка комментариев либо включается, либо отключается безусловно.

    References: #9142

2.0.0rc3

Released: January 18, 2023

orm

  • [orm] [feature]

    В директиве Mapper добавлен новый параметр Mapper.polymorphic_abstract. Эта директива предназначена для того, чтобы ORM не считала класс инстанцированным или загруженным напрямую, а только подклассы. Фактический эффект заключается в том, что Mapper будет препятствовать прямому инстанцированию экземпляров класса и будет ожидать, что класс не имеет определенной полиморфной идентичности.

    На практике класс, сопоставленный с помощью Mapper.polymorphic_abstract, может использоваться как цель relationship(), а также применяться в запросах; подклассы, разумеется, должны включать в свои сопоставления полиморфные тождества.

    Новый параметр автоматически применяется к классам, которые являются подклассами класса AbstractConcreteBase, поскольку этот класс не предназначен для инстанцирования.

    References: #9060

  • [orm] [bug]

    Исправлена проблема, при которой использование типа pep-593 Annotated в registry.type_annotation_map, который сам содержал общий простой контейнер или тип collections.abc (например, list, dict, collections.abc.Sequence и т.д.) в качестве целевого типа, приводило к внутренней ошибке, когда ORM пытались интерпретировать экземпляр Annotated.

    References: #9099

  • [orm] [bug]

    Добавлено сообщение об ошибке при сопоставлении relationship() с абстрактным типом контейнера, например Mapped[Sequence[B]], без указания параметра relationship.container_class, который необходим, когда тип является абстрактным. Ранее абстрактный контейнер пытался быть инстанцирован на более позднем шаге и терпел неудачу.

    References: #9100

sql

  • [sql] [bug]

    Исправлена ошибка/регрессия, при которой использование bindparam() с тем же именем, что и столбец, в методе Update.values() в Update, а также в методе Insert.values() в Insert только в версии 2.0 в некоторых случаях приводило к тому, что SQL-выражение, в котором был представлен параметр, не выполнялось, заменяясь новым параметром с тем же именем и отбрасывая все остальные элементы SQL-выражения, такие как SQL-функции и т.д. В данном случае речь идет об операторах, построенных на основе сущностей ORM, а не простых экземпляров Table, но это может произойти и в том случае, если оператор был вызван с помощью Session или Connection.

    Update часть проблемы присутствовала как в 2.0, так и в 1.4 и перенесена в 1.4.

    This change is also backported to: 1.4.47

    References: #9075

typing

  • [typing] [bug]

    Исправления в аннотациях расширения sqlalchemy.ext.hybrid для более эффективной типизации пользовательских методов. При типизации теперь используются возможности PEP 612, поддерживаемые последними версиями Mypy, для сохранения сигнатур аргументов для hybrid_method. Возвращаемые значения для гибридных методов принимаются как SQL-выражения в таких контекстах, как Select.where(), при этом сохраняется поддержка SQL-методов.

    References: #9096

mypy

  • [mypy] [bug]

    В плагин mypy внесены коррективы, учитывающие некоторые потенциальные изменения, которые могут быть внесены в проблему #236 sqlalchemy2-stubs при использовании SQLAlchemy 1.4. Эти изменения синхронизируются с SQLAlchemy 2.0. Изменения также обратно совместимы со старыми версиями sqlalchemy2-stubs.

    This change is also backported to: 1.4.47

  • [mypy] [bug]

    Исправлен сбой в плагине mypy, который мог произойти как в версии 1.4, так и в версии 2.0, если использовался декоратор для декоратора mapped(), на который ссылалось выражение, содержащее более двух компонентов (например, @Backend.mapper_registry.mapped). Теперь этот сценарий игнорируется; при использовании плагина выражение декоратора должно быть двухкомпонентным (т.е. @reg.mapped).

    This change is also backported to: 1.4.47

    References: #9102

postgresql

  • [postgresql] [bug]

    Исправлена регрессия, в результате которой в версии 3.1.8 в вызове API psycopg3 было изменено ожидание определенного типа объекта, которое ранее не соблюдалось, что нарушало связь с диалектом psycopg3.

    References: #9106

oracle

  • [oracle] [usecase]

    Добавлена поддержка SQL-типа Oracle TIMESTAMP WITH LOCAL TIME ZONE, использующего недавно добавленный специфический для Oracle тип данных TIMESTAMP.

    References: #9086

2.0.0rc2

Released: January 9, 2023

orm

  • [orm] [bug]

    Исправлена проблема, связанная с тем, что в версии 2.0 было добавлено слишком ограничительное правило отображения ORM, которое не позволяло выполнять отображение на объекты TableClause, например, на те, которые используются в рецепте представления на вики.

    References: #9071

typing

  • [typing] [bug]

    В принятой версии PEP 681 аргумент Data Class Transforms field_descriptors был переименован в field_specifiers.

    References: #9067

postgresql

mysql

  • [mysql] [bug]

    Восстановлено поведение Inspector.has_table() для сообщения о временных таблицах для MySQL / MariaDB. В настоящее время это поведение характерно для всех остальных диалектов, но было удалено для MySQL в версии 1.4 в связи с тем, что команда DESCRIBE больше не используется; в этой или предыдущей версии не было документированной поддержки для сообщения о временных таблицах методом Inspector.has_table(), поэтому предыдущее поведение было неопределенным.

    Поскольку в SQLAlchemy 2.0 добавлена формальная поддержка состояния временных таблиц через Inspector.has_table(), диалект MySQL /MariaDB был возвращен к использованию оператора «DESCRIBE», как это было в серии SQLAlchemy 1.3 и ранее, и добавлена тестовая поддержка такого поведения MySQL / MariaDB. Прежние проблемы с выбросом ROLLBACK, которые пытались решить в версии 1.4, в SQLAlchemy 2.0 не применяются в связи с упрощением обработки транзакций Connection.

    DESCRIBE необходим, так как в MariaDB, в частности, нет какой-либо общедоступной схемы для создания отчетов о временных таблицах, кроме DESCRIBE/SHOW COLUMNS, которые полагаются на выброс ошибки, чтобы сообщить об отсутствии результатов.

    References: #9058

oracle

  • [oracle] [bug]

    Поддерживается вариант использования ограничений по внешнему ключу, когда локальный столбец помечен как «невидимый». Ошибки, обычно генерируемые при создании ForeignKeyConstraint, которые проверяют наличие целевого столбца, при отражении отключаются, и ограничение пропускается с предупреждением, аналогично тому, как это уже происходит для Index с подобной проблемой.

    References: #9059

2.0.0rc1

Released: December 28, 2022

general

  • [general] [bug]

    Исправлена регрессия, при которой базовый модуль compat обращался к platform.architecture() для определения некоторых свойств системы, что приводило к слишком широкому вызову системы по сравнению с вызовом системного уровня file, недоступному при некоторых обстоятельствах, в том числе в некоторых конфигурациях безопасного окружения.

    This change is also backported to: 1.4.46

    References: #8995

orm

  • [orm] [feature]

    Добавлено новое значение по умолчанию для параметра Mapper.eager_defaults «auto», который будет автоматически извлекать значения по умолчанию таблицы во время промывки единицы работы, если диалект поддерживает RETURNING для выполняемого INSERT, а также доступно значение insertmanyvalues. Поспешная выборка значений по умолчанию для UPDATE на стороне сервера, что бывает очень редко, по-прежнему происходит только при установке Mapper.eager_defaults в значение True, поскольку для операторов UPDATE не существует формы пакетного RETURNING.

    References: #8889

  • [orm] [usecase]

    Корректировка Session с точки зрения расширяемости, а также обновление расширения ShardedSession:

    • Session.get() теперь принимает Session.get.bind_arguments, что, в частности, может быть полезно при использовании расширения горизонтального шардинга.

    • Session.get_bind() принимает произвольные аргументы kw, что облегчает разработку кода, использующего класс Session, который переопределяет этот метод с дополнительными аргументами.

    • Добавлена новая опция выполнения ORM identity_token, с помощью которой можно напрямую влиять на «токен идентичности», который будет ассоциирован с вновь загруженными объектами ORM. Этот маркер используется в подходах шардинга (в частности, ShardedSession, но может быть использован и в других случаях) для разделения идентификаторов объектов по разным «шардам».

    • Событийный крючок SessionEvents.do_orm_execute() теперь может использоваться для воздействия на все опции, связанные с ORM, включая autoflush, populate_existing и yield_per; эти опции повторно обрабатываются после вызова событийных крючков, прежде чем они будут применены. Ранее опции типа autoflush уже оценивались в этот момент. В этом режиме также поддерживается новая опция identity_token, которая теперь используется расширением горизонтального шардинга.

    • Класс ShardedSession заменяет хук ShardedSession.id_chooser новым хуком ShardedSession.identity_chooser, который больше не опирается на устаревший объект Query. Вместо ShardedSession.id_chooser по-прежнему принимается ShardedSession.identity_chooser с предупреждением об устаревании.

    References: #7837

  • [orm] [usecase]

    Поведение «присоединения внешней транзакции к сессии» было пересмотрено и улучшено, что позволяет явно контролировать, как Session будет воспринимать входящую Connection, которая уже имеет транзакцию и, возможно, точку сохранения. Новый параметр Session.join_transaction_mode включает в себя ряд опций, которые могут учитывать существующую транзакцию несколькими способами, наиболее важным из которых является то, что Session может работать в полностью транзакционном стиле, используя исключительно точки сохранения, оставляя инициированную извне транзакцию нефиксированной и активной при любых обстоятельствах, что позволяет тестовым наборам откатывать все изменения, происходящие внутри тестов.

    Кроме того, пересмотрен метод Session.close() для полного закрытия точек сохранения, которые еще могут присутствовать, что также позволяет рецепту «внешней транзакции» работать без предупреждений, если Session не завершил явным образом свои собственные транзакции SAVEPOINT.

    References: #9015

  • [orm] [usecase]

    Устранено требование использования атрибута __allow_unmapped__ в декларативном классе, отображаемом на Dataclass, при обнаружении аннотаций не``Mapped[]``; ранее выдавалось сообщение об ошибке, предназначенное для поддержки устаревших типизированных отображений ORM, в котором дополнительно не упоминались правильные паттерны для использования именно с Dataclass. Теперь это сообщение об ошибке больше не выдается, если используется registry.mapped_as_dataclass() или MappedAsDataclass.

    References: #8973

  • [orm] [bug]

    Исправлена проблема внутреннего обхода SQL для операторов DML типа Update и Delete, которая приводила, помимо прочих потенциальных проблем, к специфической проблеме использования лямбда-операторов с функцией обновления/удаления ORM.

    This change is also backported to: 1.4.46

    References: #9033

  • [orm] [bug]

    Исправлена ошибка, при которой Session.merge() не сохранял текущее загруженное содержимое атрибутов отношений, указанных параметром relationship.viewonly, что приводило к нарушению стратегий, использующих Session.merge() для извлечения полностью загруженных объектов из кэша и других подобных приемов. В связанном с этим изменении исправлена проблема, когда объект, содержащий загруженное отношение, которое, тем не менее, было настроено как lazy='raise' на отображении, терпел неудачу при передаче в Session.merge(); теперь проверка на «повышение» приостанавливается в процессе слияния, предполагая, что параметр Session.merge.load остается по умолчанию True.

    В целом это поведенческая корректировка изменения, введенного в серии 1.4 начиная с версии #4994, которое убрало «слияние» из набора каскадов, применяемых по умолчанию к отношениям «только для просмотра». Поскольку отношения «viewonly» не сохраняются ни при каких обстоятельствах, разрешение передачи их содержимого при «merge» не влияет на поведение сохранения целевого объекта. Это позволяет Session.merge() корректно использовать один из вариантов его применения - добавление в Session объектов, которые были загружены в другом месте, часто для восстановления из кэша.

    This change is also backported to: 1.4.45

    References: #8862

  • [orm] [bug]

    Исправлены проблемы в with_expression(), когда выражения, состоящие из столбцов, на которые есть ссылки из вложенного SELECT, в некоторых контекстах не выводили корректный SQL, в случае если выражение имело имя метки, совпадающее с атрибутом, который использовал query_expression(), даже если query_expression() не имел выражения по умолчанию. На данный момент, если выражение query_expression() все же имеет выражение по умолчанию, то это имя метки все равно используется по умолчанию, а дополнительная метка с тем же именем будет по-прежнему игнорироваться. В целом, данный случай является довольно сложным, поэтому, возможно, потребуются дополнительные корректировки.

    This change is also backported to: 1.4.45

    References: #8881

  • [orm] [bug]

    Если имя обратной ссылки, используемое в relationship(), называет атрибут целевого класса, которому уже присвоено имя метода или атрибута, то выдается предупреждение, поскольку объявление обратной ссылки заменит этот атрибут.

    References: #4629

  • [orm] [bug]

    Ряд изменений и улучшений, касающихся Session.refresh(). Общее изменение заключается в том, что атрибуты первичного ключа объекта теперь включаются в операцию обновления безусловно, если должны быть обновлены атрибуты, связанные с отношениями, даже если срок их действия не истек и если они не указаны в обновлении.

    • Улучшена функция Session.refresh(), благодаря которой, если включена автопромывка (как по умолчанию для Session), автопромывка происходит в более ранней части процесса обновления, что позволяет применить ожидаемые изменения первичного ключа без возникновения ошибок. Ранее автоочистка происходила слишком поздно, и оператор SELECT не использовал правильный ключ для нахождения строки, в результате чего возникала ошибка InvalidRequestError.

    • Когда выполняется описанное выше условие, т.е. в объекте присутствуют непромытые изменения первичного ключа, но автопромывка не включена, метод refresh() теперь явно запрещает выполнение операции, и выдается информационное сообщение InvalidRequestError с просьбой сначала промыть непромытые изменения первичного ключа. Ранее такой вариант использования был просто нерабочим, и сообщение InvalidRequestError выдавалось в любом случае. Это ограничение сделано для того, чтобы атрибуты первичного ключа были безопасно обновлены, как это необходимо для случая, когда можно обновить объект, при этом также будут выдаваться связанные с отношениями вторичные eagerloader’ы. Это правило применяется во всех случаях, чтобы обеспечить согласованность поведения API независимо от того, нужны ли PK-ключи при обновлении, поскольку необычно обновлять одни атрибуты объекта, оставляя другие атрибуты «в ожидании» в любом случае.

    • Метод Session.refresh() был усовершенствован таким образом, что атрибуты, которые связаны с relationship() и привязаны к ускоренному загрузчику либо во время отображения, либо через последние использованные опции загрузчика, будут обновляться во всех случаях, даже если передан список атрибутов, не включающий ни одного столбца родительской строки. Это основано на возможности, впервые реализованной для нестолбцовых атрибутов в рамках #1763, исправленной в 1.4, позволяющей нетерпеливо загружаемым атрибутам, связанным отношениями, участвовать в операции Session.refresh(). Если в операции обновления не указано ни одного столбца родительской строки, подлежащего обновлению, столбцы первичного ключа, тем не менее, будут включены в операцию обновления, что позволит продолжить загрузку во вторичные загрузчики отношений, как это происходит обычно. Ранее для этого условия возникала ошибка InvalidRequestError (#8703)

    • Исправлена проблема, при которой в случае вызова Session.refresh() с комбинацией атрибутов с истекшим сроком действия, а также загрузчика, например selectinload(), выполняющего «вторичный» запрос, если атрибуты первичного ключа также находились в истекшем состоянии, выдавался ненужный дополнительный SELECT. Поскольку атрибуты первичного ключа теперь включаются в обновление автоматически, не возникает дополнительной нагрузки на эти атрибуты, когда загрузчик отношений переходит к выборке по ним (#8997)

    • Исправлена регрессия, вызванная выпуском #8126 в версии 2.0.0b1, когда метод Session.refresh() выдавал ошибку AttributeError, если ему передавалось как имя столбца с истекшим сроком хранения, так и имя атрибута, связанного с отношениями, который был связан с «вторичным» ускоренным загрузчиком, таким как selectinload() (#8996)

    References: #8703, #8996, #8997

  • [orm] [bug]

    Исправлено исправление, впервые сделанное в версии 1.4 для #8456, которое уменьшало использование внутренних «полиморфных адаптеров», используемых для вывода ORM-запросов при использовании параметра Mapper.with_polymorphic. Эти адаптеры, очень сложные и склонные к ошибкам, теперь используются только в тех случаях, когда для Mapper.with_polymorphic используется явный пользовательский подзапрос, что включает только случай использования конкретных отображений наследования, использующих помощник polymorphic_union(), а также унаследованный случай использования алиасированного подзапроса для объединенных отображений наследования, который в современном использовании не нужен.

    Для наиболее распространенного случая отображений объединенного наследования, использующих встроенную схему полиморфной загрузки, к которым относятся и те, которые используют параметр Mapper.polymorphic_load, установленный в значение inline, полиморфные адаптеры теперь не используются. Это положительно сказывается как на производительности построения запросов, так и на существенном упрощении внутреннего процесса визуализации запросов.

    Конкретная проблема заключалась в том, чтобы позволить column_property() ссылаться на объединенные классы наследования в скалярном подзапросе, что теперь работает настолько интуитивно, насколько это возможно.

    References: #8168

engine

  • [engine] [bug]

    Исправлено давнее состояние гонки в пуле соединений, которое могло возникать при использовании схем eventlet/gevent monkeypatching в сочетании с условиями eventlet/gevent Timeout, когда проверка пула соединений, прерванная из-за таймаута, не успевала очистить состояние отказа, что приводило к «утечке» базовой записи соединения, а иногда и самого соединения с базой данных, оставляя пул в неработоспособном состоянии с недоступными записями. Впервые эта проблема была выявлена и исправлена в SQLAlchemy 1.2 для #4225, однако режимы отказа, обнаруженные в этом исправлении, не учитывали BaseException, а не Exception, что не позволяло перехватить эвентлет/гевент Timeout. Кроме того, был выявлен и исправлен блок внутри начального соединения с пулом, в котором появился блок BaseException -> «clean failed connect», учитывающий то же самое условие в этом месте. Большое спасибо пользователю Github @niklaus за упорную работу по выявлению и описанию этой сложной проблемы.

    This change is also backported to: 1.4.46

    References: #8974

  • [engine] [bug]

    Исправлена проблема, при которой метод Result.freeze() не работал для текстового SQL, использующего text() или Connection.exec_driver_sql().

    This change is also backported to: 1.4.45

    References: #8963

sql

  • [sql] [usecase]

    Теперь в случае неудачи любой операции рендеринга «literal bindparam» выбрасывается информативное сообщение re-raise с указанием самого значения и используемого типа данных, чтобы помочь в отладке при рендеринге буквальных параметров в операторе.

    This change is also backported to: 1.4.45

    References: #8800

  • [sql] [bug]

    Исправлена проблема в лямбда-функции SQL, когда вычисляемый тип литерального значения не учитывал правила коэрцитивности типа «сравнивается с типом», что приводило к отсутствию информации о типе для SQL-выражений, таких как сравнение с элементами JSON и подобных.

    This change is also backported to: 1.4.46

    References: #9029

  • [sql] [bug]

    Исправлен ряд проблем, связанных с расположением, а иногда и идентичностью отображаемых связанных параметров, например, для SQLite, asyncpg, MySQL, Oracle и других. В некоторых скомпилированных формах порядок параметров сохранялся некорректно, например, в функции PostgreSQL regexp_replace(), во «вложенной» конструкции CTE, впервые появившейся в #4123, а также в таблицах с выбором, сформированных методом FunctionElement.column_valued() в Oracle.

    This change is also backported to: 1.4.45

    References: #8827

  • [sql] [bug]

    Добавлена поддержка теста на то, что все методы компилятора visit_xyz() во всех реализациях Compiler в SQLAlchemy принимают параметр **kw, так что все компиляторы принимают дополнительные аргументы в виде ключевых слов при любых обстоятельствах.

    References: #8988

  • [sql] [bug]

    Метод SQLCompiler.construct_params(), как и аксессор SQLCompiler.params, теперь будет возвращать именно те параметры, которые соответствуют скомпилированному оператору, использовавшему для компиляции параметр render_postcompile. Ранее метод возвращал структуру параметров, которая сама по себе не соответствовала ни исходным, ни расширенным параметрам.

    Передача нового словаря параметров в SQLCompiler.construct_params() для SQLCompiler, построенного с помощью render_postcompile, теперь запрещена; вместо этого для создания новой SQL-строки и набора параметров для альтернативного набора параметров добавлен новый метод SQLCompiler.construct_expanded_state(), который будет создавать новую расширенную форму для заданного набора параметров, используя контейнер ExpandedState, включающий новый SQL-оператор и новый словарь параметров, а также кортеж позиционных параметров.

    References: #6114

  • [sql] [bug]

    Для адаптации к сторонним диалектам с различными требованиями к экранированию символов в связанных параметрах, система, с помощью которой SQLAlchemy «экранирует» (т.е. заменяет другим символом) специальные символы в именах связанных параметров, была расширена для сторонних диалектов, используя словарь SQLCompiler.bindname_escape_chars, который может быть переопределен на уровне объявления класса для любого подкласса SQLCompiler. В рамках этого изменения также добавлена точка "." в качестве «экранированного» символа по умолчанию.

    References: #8994

typing

  • [typing] [bug]

    Завершена типизация pep-484 для расширения sqlalchemy.ext.horizontal_shard, а также модуля sqlalchemy.orm.events. Спасибо Глебу Кисенкову за проделанную работу.

    References: #6810, #9025

asyncio

  • [asyncio] [bug]

    Из AsyncResult удален нефункциональный метод merge(). Этот метод никогда не работал и был включен в AsyncResult по ошибке.

    This change is also backported to: 1.4.45

    References: #8952

postgresql

  • [postgresql] [bug]

    Исправлена ошибка, при которой параметр PostgreSQL Insert.on_conflict_do_update.constraint принимал объект Index, но не разворачивал этот индекс в отдельные индексные выражения, а вместо этого выводил его имя в предложение ON CONFLICT ON CONSTRAINT, которое не принимается PostgreSQL; форма «constraint name» принимает только уникальные или исключающие имена ограничений. Параметр продолжает принимать индекс, но теперь разлагает его на составные выражения для рендеринга.

    This change is also backported to: 1.4.46

    References: #9023

  • [postgresql] [bug]

    Внесена поправка в то, как диалект PostgreSQL учитывает типы столбцов при отражении столбцов из таблицы, для учета альтернативных бэкендов, которые могут возвращать NULL из функции PG format_type().

    This change is also backported to: 1.4.45

    References: #8748

  • [postgresql] [bug]

    Добавлена поддержка явного использования полнотекстовых функций PG с asyncpg и psycopg (только для SQLAlchemy 2.0) в части приведения типа REGCONFIG для первого аргумента, который ранее неверно приводился к VARCHAR, что приводило к сбоям в этих диалектах, полагающихся на явное приведение типов. Это включает поддержку диалектов to_tsvector, to_tsquery, plainto_tsquery, phraseto_tsquery, websearch_to_tsquery, ts_headline, каждый из которых в зависимости от количества переданных аргументов определяет, следует ли интерпретировать первый строковый аргумент как значение PostgreSQL «REGCONFIG»; если да, то аргумент типизируется с помощью нового объекта типа REGCONFIG, который затем явно приводится в выражении SQL.

    References: #8977

  • [postgresql] [bug]

    Исправлена ошибка, при которой вновь переработанные типы диапазонов PostgreSQL, такие как INT4RANGE, не могли быть установлены в качестве имплантов пользовательского типа TypeDecorator, вместо этого вызывая TypeError.

    References: #9020

  • [postgresql] [bug]

    Теперь при сравнении с экземпляром другого класса Range.__eq___() будет возвращаться NotImplemented, а не вызывать исключение AttributeError.

    References: #8984

sqlite

  • [sqlite] [usecase]

    Добавлена поддержка бэкенда SQLite для отражения ключевых слов «DEFERRABLE» и «INITIALLY», которые могут присутствовать в конструкции внешнего ключа. Pull request любезно предоставлен Майклом Горвеном.

    This change is also backported to: 1.4.45

    References: #8903

  • [sqlite] [usecase]

    Добавлена поддержка отражения ориентированных на выражения критериев WHERE, включенных в индексы на диалекте SQLite, аналогично тому, как это делается на диалекте PostgreSQL. Pull request любезно предоставлен Тобиасом Пфайффером.

    This change is also backported to: 1.4.45

    References: #8804

oracle

  • [oracle] [bug]

    Исправлена проблема в компиляторе Oracle, когда синтаксис для FunctionElement.column_valued() был неверен, что приводило к появлению имени COLUMN_VALUE без корректной квалификации исходной таблицы.

    This change is also backported to: 1.4.45

    References: #8945

tests

  • [tests] [bug]

    Исправлена проблема в файле tox.ini, когда изменения в серии tox 4.0 в формате «passenv» приводили к некорректной работе tox, в частности, вызывая ошибку начиная с tox 4.0.6.

    This change is also backported to: 1.4.46

  • [tests] [bug]

    Добавлено новое правило исключения для сторонних диалектов unusual_column_name_characters, которое может быть «закрыто» для сторонних диалектов, не поддерживающих имена колонок с необычными символами, такими как точки, косые черты или знаки процента, даже если имя правильно заключено в кавычки.

    This change is also backported to: 1.4.46

    References: #9002

2.0.0b4

Released: December 5, 2022

orm

  • [orm] [feature]

    Добавлен новый параметр mapped_column.use_existing_column для реализации случая наследования одной таблицы, в котором используется схема, когда более одного подкласса указывают на один и тот же столбец в суперклассе. Ранее этот паттерн был возможен при использовании declared_attr() в сочетании с размещением существующего столбца в .__table__ суперкласса, однако теперь он обновлен для работы с mapped_column(), а также с типизацией pep-484, простым и лаконичным способом.

    См.также

    ``use_existing_column``R

    References: #8822

  • [orm] [usecase]

    Добавлена поддержка автоматического преобразования пользовательских типов, расширяющих базовый класс Python enum.Enum, в SQLAlchemy Enum SQL-типы при использовании функции Annotated Declarative Table. Данная возможность стала возможной благодаря новым функциям поиска, добавленным в функцию ORM type map, и включает поддержку изменения аргументов Enum, генерируемых по умолчанию, а также настройку конкретных enum.Enum типов внутри карты с определенными аргументами.

    References: #8859

  • [orm] [usecase]

    Добавлен параметр mapped_column.compare в соответствующие конструкции атрибутов ORM, включая mapped_column(), relationship() и т.д. для обеспечения параметра Python dataclasses compare на field() при использовании возможности Декларативное отображение классов данных. Pull request любезно предоставлен Simon Schiele.

    References: #8905

  • [orm] [bug]

    Исправлена проблема, при которой использование неизвестного типа данных в аннотации Mapped для атрибута, основанного на столбце, приводило к молчаливому отказу в отображении атрибута, а не к сообщению об исключении; теперь выдается информативное сообщение об исключении.

    References: #8888

  • [orm] [bug]

    Исправлен ряд проблем, связанных с тем, что использование Mapped со словарными типами, такими как Mapped[Dict[str, str] | None], некорректно интерпретировалось в декларативных ORM-маппингах. Исправлена поддержка корректной «деопционализации» этого типа, в том числе для поиска в type_annotation_map.

    References: #8777

  • [orm] [bug] [performance]

    Дополнительное повышение производительности SQL-запросов с поддержкой ORM, в частности, повышение производительности подсчета вызовов при построении ORM-запросов с использованием комбинаций aliased() с union() и подобных «составных» конструкций, а также прямое повышение производительности внутреннего метода corresponding_column(), который активно используется в ORM с помощью конструкций типа aliased() и подобных.

    References: #8796

  • [orm] [bug]

    Исправлена ошибка в функции Декларативное отображение классов данных, когда использование в отображении простых полей класса данных с директивой __allow_unmapped__ не создавало класс данных с правильным состоянием уровня класса для этих полей, копируя в класс необработанный объект Field после замены объекта Field значением по умолчанию на уровне класса.

    References: #8880

  • [orm] [bug] [regression]

    Исправлена ошибка, при которой при использовании параметра Mapper.eager_defaults происходила неудачная очистка сопоставленного класса, сопоставленного с подзапросом, например, при прямом сопоставлении или некоторых формах наследования конкретных таблиц.

    References: #8812

  • [orm] [bug]

    В версии 2.0.0b3 исправлена ошибка, связанная с #8759, когда при указании имени Mapped с помощью квалифицированного имени, например sqlalchemy.orm.Mapped, Declarative не распознавал конструкцию как указывающую на Mapped.

    References: #8853

orm extensions

  • [usecase] [orm extensions]

    Добавлена поддержка функции расширения association_proxy() для участия в конфигурации Python dataclasses при использовании функции native dataclasses, описанной в Декларативное отображение классов данных. Включены аргументы на уровне атрибутов, в том числе association_proxy.init и association_proxy.default_factory.

    Документация по ассоциативным прокси также была обновлена для использования в примерах формы «Аннотированная декларативная таблица», включая аннотации типов, используемые для самого AssocationProxy.

    References: #8878

sql

  • [sql] [usecase]

    Добавлен класс ScalarValues, который может использоваться в качестве элемента колонки, что позволяет использовать Values внутри предложений IN или в сочетании с агрегатами коллекций ANY или ALL. Новый класс генерируется с помощью метода Values.scalar_values(). Экземпляр Values теперь принудительно преобразуется в ScalarValues при использовании в операциях IN или NOT IN.

    References: #6289

  • [sql] [bug]

    Исправлена критическая проблема с памятью при генерации ключей кэша, когда для очень больших и сложных ORM-выражений, использующих множество ORM-псевдонимов с подзапросами, генерация ключей кэша могла приводить к созданию слишком больших ключей, на порядки превышающих размер самого выражения. Большое спасибо Rollo Konig Brock за их очень терпеливую и длительную помощь в выявлении этой проблемы.

    This change is also backported to: 1.4.44

    References: #8790

  • [sql] [bug]

    Подход к параметру numeric pep-249 paramstyle был переписан и теперь полностью поддерживается, в том числе такими функциями, как «expanding IN» и «insertmanyvalues». Имена параметров также могут повторяться в исходной SQL-конструкции, что будет корректно представлено в числовом формате с использованием одного параметра. Введен дополнительный числовой стиль параметров numeric_dollar, который используется в диалекте asyncpg; этот стиль эквивалентен numeric, за исключением того, что числовые индикаторы обозначаются знаком доллара, а не двоеточием. Диалект asyncpg теперь использует парамстиль numeric_dollar напрямую, а не компилирует сначала стиль format.

    Стили параметров numeric и numeric_dollar предполагают, что целевой бэкенд способен принимать числовые параметры в любом порядке, и будет подставлять значения заданных параметров в утверждение на основе соответствия их позиции (на основе 1) числовому индикатору. Это нормальное поведение «числовых» стилей параметров, хотя было замечено, что в SQLite DBAPI реализован неиспользуемый «числовой» стиль, который не учитывает упорядочивание параметров.

    References: #8849

  • [sql] [bug]

    Скорректировано отображение RETURNING, в частности, при использовании Insert, таким образом, что теперь столбцы отображаются с использованием той же логики, что и в конструкции Select для генерации меток, которая включает в себя недвусмысленные метки, а также то, что SQL-функция, окружающая именованный столбец, будет обозначаться с использованием самого имени столбца. Это обеспечивает лучшую кросс-совместимость при выборе строк как из конструкций Select, так и из операторов DML, использующих UpdateBase.returning(). Для серии 1.4 также было сделано более узкое изменение, корректирующее только вопрос с метками функций.

    References: #8770

schema

typing

  • [typing] [usecase]

    Добавлен новый тип SQLColumnExpression, который может быть указан в пользовательском коде для представления любого выражения, ориентированного на столбец SQL, включая как те, которые основаны на ColumnElement, так и на ORM QueryableAttribute. Этот тип является реальным классом, а не псевдонимом, поэтому может быть использован в качестве основы для других объектов. Также включен дополнительный подкласс SQLORMExpression, специфичный для ORM.

    References: #8847

  • [typing] [bug]

    Скорректировано внутреннее использование класса Python enum.IntFlag, который изменил свой поведенческий контракт в Python 3.11. Это не приводило к сбоям во время выполнения программы, но приводило к сбоям при наборе текста в Python 3.11.

    References: #8783

  • [typing] [bug]

    Расширения sqlalchemy.ext.mutable и sqlalchemy.ext.automap теперь полностью типизированы в pep-484. Огромная благодарность Глебу Кисенкову за проделанную работу.

    References: #6810, #8667

  • [typing] [bug]

    Исправлена поддержка типизации для аргумента relationship.secondary, который также может принимать вызываемую переменную (лямбду), возвращающую FromClause.

  • [typing] [bug]

    Улучшена типизация для sessionmaker и async_sessionmaker, так что по умолчанию их возвращаемое значение будет иметь тип Session или AsyncSession, без необходимости вводить это явно. Ранее Mypy не мог автоматически вывести эти типы возвращаемых значений из своей базы generic.

    В рамках этого изменения аргументы для Session, AsyncSession, sessionmaker и async_sessionmaker, помимо начального аргумента «bind», стали только ключевыми, что включает параметры, которые всегда документировались как ключевые, такие как Session.autoflush, Session.class_ и т.д.

    Pull request courtesy Sam Bull.

    References: #8842

  • [typing] [bug]

    Исправлена проблема, при которой передача вызываемой функции, возвращающей итерабель элементов столбцов, в relationship.order_by отмечалась как ошибка в программах проверки типов.

    References: #8776

postgresql

  • [postgresql] [usecase]

    В дополнение к #8690 в объекты диапазонов, специфичные для PG, были добавлены новые методы сравнения Range.adjacent_to(), Range.difference(), Range.union() и т.д., что позволило привести их в соответствие со стандартными операторами, реализуемыми базовым AbstractRange.comparator_factory.

    Кроме того, метод __bool__() класса был исправлен, чтобы соответствовать обычному поведению контейнеров Python, а также поведению других популярных драйверов PostgreSQL: теперь он определяет, является ли экземпляр диапазона не пустым, а не наоборот.

    Pull request courtesy Lele Gaifax.

    References: #8765

  • [postgresql] [change] [asyncpg]

    Изменен paramstyle, используемый asyncpg, с format на numeric_dollar. Это имеет два основных преимущества, поскольку не требует дополнительной обработки оператора и позволяет использовать в операторах дублирующие параметры.

    References: #8926

  • [postgresql] [bug] [mssql]

    Только для диалектов PostgreSQL и SQL Server компилятор настроен таким образом, что при выводе выражений столбцов в предложении RETURNING для элементов SQL-выражений, генерирующих метку, предлагается использовать метку «non anon», которая используется в операторах SELECT; основным примером является SQL-функция, которая может выдаваться как часть типа столбца, где имя метки по умолчанию должно совпадать с именем столбца. Это восстанавливает не вполне определенное поведение, которое изменилось в версии 1.4.21 из-за #6718, #6710. Диалект Oracle имеет другую реализацию RETURNING и не был затронут этой проблемой. В версии 2.0 внесены общие изменения для широкого расширения поддержки RETURNING в других бэкендах.

    This change is also backported to: 1.4.44

    References: #8770

  • [postgresql] [bug]

    Добавлено дополнительное определение типа для нового типа PostgreSQL Range, когда предыдущие случаи, позволявшие получать объекты psycopg2-native range напрямую в DBAPI без перехвата их SQLAlchemy, перестали работать, так как теперь у нас есть собственный объект value. Объект Range был усовершенствован таким образом, что SQLAlchemy Core обнаруживает его в других неоднозначных ситуациях (например, при сравнении с датами) и применяет соответствующие обработчики связывания. Pull request любезно предоставлен Lele Gaifax.

    References: #8884

mssql

  • [mssql] [bug]

    Исправлена регрессия, вызванная комбинацией команды #8177, повторно включающей setinputsizes для SQL server, если для оператора не используется fast_executemany + DBAPI executemany, и команды #6047, реализующей «insertmanyvalues», которая обходит DBAPI executemany вместо пользовательского DBAPI execute для операторов INSERT. При включении fast_executemany проверка некорректно не будет использовать setinputsizes для INSERT-оператора с несколькими параметрами, использующего «insertmanyvalues», так как будет ошибочно считать, что это вызов DBAPI executemany. В этом случае «регресс» будет заключаться в том, что формат оператора «insertmanyvalues», по-видимому, несколько более чувствителен к множественным строкам, в которых не используются одинаковые типы для каждой строки, поэтому в таком случае setinputsizes особенно необходим.

    Исправление исправляет проверку fast_executemany таким образом, чтобы она отключала setinputsizes только в случае использования истинного DBAPI executemany.

    References: #8917

oracle

  • [oracle] [bug]

    Продолжение исправления ошибки Oracle #8708, выпущенной в версии 1.4.43, в которой имена связанных параметров, начинающиеся с символов подчеркивания, запрещенных Oracle, все еще не приводились в надлежащий вид при любых обстоятельствах.

    This change is also backported to: 1.4.45

    References: #8708

tests

  • [tests] [bug]

    Исправлена проблема, при которой параметр --disable-asyncio в тестовом наборе не запускал тесты greenlet, а также не предотвращал использование «оберточного» greenlet для всего набора. Теперь этот параметр гарантирует, что в течение всего прогона не будет использоваться greenlet или asyncio.

    This change is also backported to: 1.4.44

    References: #8793

2.0.0b3

Released: November 4, 2022

orm

  • [orm] [bug]

    Исправлена проблема в объединенной ускоренной загрузке, когда при определенной комбинации внешней/внутренней объединенной ускоренной загрузки происходил сбой утверждения при ускоренной загрузке трех мэпперов, где средний мэппер был унаследованным мэппером подкласса.

    This change is also backported to: 1.4.43

    References: #8738

  • [orm] [bug]

    Исправлена ошибка, связанная с конструкциями Select, когда комбинации Select.select_from() с Select.join(), а также при использовании Select.join_from() приводили к тому, что функция with_loader_criteria(), а также критерии IN, необходимые для запросов наследования одной таблицы, не отображались в тех случаях, когда в предложении columns запроса не была явно указана левая сторона сущности JOIN. Теперь правильная сущность передается в объект Join, который генерируется внутренне, что позволяет корректно добавлять критерии к левосторонней сущности.

    This change is also backported to: 1.4.43

    References: #8721

  • [orm] [bug]

    При использовании опции with_loader_criteria() в качестве опции загрузчика, добавленной к определенному «пути загрузчика», например, при использовании ее внутри Load.options(), теперь выдается информативное исключение. Такое использование не поддерживается, поскольку with_loader_criteria() предназначена только для использования в качестве опции загрузчика верхнего уровня. Ранее возникала внутренняя ошибка.

    This change is also backported to: 1.4.43

    References: #8711

  • [orm] [bug]

    Улучшен «режим словаря» для Session.get(), благодаря чему имена синонимов, ссылающиеся на имена атрибутов первичного ключа, могут быть указаны в именованном словаре.

    This change is also backported to: 1.4.43

    References: #8753

  • [orm] [bug]

    Исправлена проблема, при которой загрузка «selectin_polymorphic» для отображателей наследования работала некорректно, если параметр Mapper.polymorphic_on ссылался на SQL-выражение, которое не было непосредственно отображено на класс.

    This change is also backported to: 1.4.43

    References: #8704

  • [orm] [bug]

    Исправлена проблема, когда при использовании объекта Query в качестве итератора базовый курсор DBAPI не закрывался, если в процессе итерации возникало определенное пользователем исключение, что приводило к закрытию итератора интерпретатором Python. При использовании Query.yield_per() для создания курсоров на стороне сервера это приводило к обычным для MySQL проблемам, связанным с рассинхронизацией курсоров на стороне сервера, и без прямого доступа к объекту Result код конечного пользователя не мог получить доступ к курсору, чтобы закрыть его.

    Для решения проблемы внутри метода итератора применяется catch для GeneratorExit, который закроет объект result в тех случаях, когда итератор был прерван, и по определению будет закрыт интерпретатором Python.

    В рамках этого изменения, реализованного в серии 1.4, было обеспечено наличие методов .close() во всех реализациях Result, включая ScalarResult, MappingResult. В версии 2.0 это изменение также включает новые паттерны менеджера контекста для использования с классами Result.

    This change is also backported to: 1.4.43

    References: #8710

orm declarative

  • [orm] [declarative] [bug]

    В декларативных аннотациях ORM добавлена поддержка того, что имена классов, указанные для relationship(), а также имя самого символа Mapped могут отличаться от прямого имени класса, что позволяет поддерживать сценарии, в которых Mapped импортируется как from sqlalchemy.orm import Mapped as M, или когда смежные имена классов импортируются с альтернативным именем аналогичным образом. Кроме того, имя целевого класса, указанное в качестве ведущего аргумента для relationship(), всегда будет заменять имя, указанное в левой аннотации, так что неимпортируемые имена, которые также не соответствуют имени класса, могут быть использованы в аннотациях.

    References: #8759

  • [orm] [declarative] [bug]

    Улучшена поддержка устаревших связок версии 1.4, использующих аннотации, не включающие Mapped[], за счет того, что атрибут __allow_unmapped__ может быть использован для пропуска таких аннотаций через Annotated Declarative без возникновения ошибки и без интерпретации в контексте времени выполнения ORM. Кроме того, улучшено сообщение об ошибке, выдаваемое при обнаружении этого условия, и добавлена дополнительная документация о том, как следует поступать в данной ситуации. К сожалению, предупреждение о миграции 1.4 WARN_SQLALCHEMY_20 не может обнаружить эту конкретную конфигурационную проблему во время выполнения при существующей архитектуре.

    References: #8692

  • [orm] [declarative] [bug]

    Изменено фундаментальное поведение конфигурации Mapper, при котором объекты Column, явно присутствующие в словаре Mapper.properties, либо непосредственно, либо заключенные в объект свойства отображения, теперь будут отображаться в том порядке, в котором они появляются в самом отображаемом Table (или другом селекте) (при условии, что они действительно являются частью списка столбцов этой таблицы), тем самым сохраняя тот же порядок столбцов в отображаемом селекте, который установлен на отображаемом классе, а также то, что отображается в операторе ORM SELECT для этого мэппера. Ранее (где «ранее» означает начиная с версии 0.0.1) объекты Column в словаре Mapper.properties всегда отображались первыми, опережая время отображения других столбцов в отображаемом Table, что вызывало несоответствие в порядке присвоения атрибутов отображаемому классу и порядке их отображения в операторах.

    Наиболее заметные изменения происходят в том, как Declarative назначает объявленные столбцы в Mapper, в частности, как обрабатываются объекты Column (или mapped_column()), если их DDL-имя явно отличается от имени отображаемого атрибута, а также когда используются такие конструкции, как deferred() и т.д. В соответствии с новым поведением порядок следования столбцов в отображенном Table будет соответствовать порядку, в котором атрибуты отображаются на класс, назначаются в самом Mapper и отображаются в операциях ORM, таких как операторы SELECT, независимо от того, как Column был сконфигурирован Mapper.

    References: #8705

  • [orm] [declarative] [bug]

    Исправлена проблема в новой функции сопоставления классов данных, когда столбец, объявленный в decalrative base / abstract base / mixin, при некоторых обстоятельствах просачивался в конструктор наследующего подкласса.

    References: #8718

  • [bug] [orm declarative]

    Исправлены проблемы в разрешителе декларативных типов (т.е. разрешающем объекты ForwardRef), когда типы, объявленные для колонок в одном конкретном исходном файле, вызывали ошибку NameError, если конечный сопоставленный класс находился в другом исходном файле. Теперь типы разрешаются в терминах модуля для каждого класса, в котором эти типы используются.

    References: #8742

engine

  • [engine] [feature]

    Для улучшения поддержки случаев итерации объектов Result и AsyncResult, когда определяемые пользователем исключения могут прервать итерацию, оба объекта, а также такие варианты, как ScalarResult, MappingResult, AsyncScalarResult, AsyncMappingResult, теперь поддерживают использование контекстного менеджера, в котором результат будет закрыт в конце блока контекстного менеджера.

    Кроме того, обеспечено наличие у всех перечисленных объектов Result метода Result.close(), а также аксессоров Result.closed, в том числе у ScalarResult и MappingResult, которые ранее не имели метода .close().

    References: #8710

  • [engine] [usecase]

    В событие PoolEvents.reset() добавлен новый параметр PoolEvents.reset.reset_state, при этом предусмотрена логика обесценивания, которая позволит продолжать принимать хуки событий с предыдущим набором аргументов. Этот параметр указывает на различную информацию о состоянии, в котором происходит сброс, и используется для реализации пользовательских схем сброса с предоставлением полного контекста.

    В рамках этого изменения включено исправление, также перенесенное в 1.4, которое позволяет событию PoolEvents.reset() продолжать происходить при любых обстоятельствах, в том числе и когда Connection уже «сбросил» соединение.

    Эти два изменения позволяют реализовать пользовательские схемы сброса с использованием события PoolEvents.reset() вместо события PoolEvents.checkin() (которое продолжает работать как и раньше).

    References: #8717

  • [engine] [bug] [regression]

    Исправлена проблема, при которой крючок события PoolEvents.reset() вызывался не во всех случаях, когда Connection был закрыт и находился в процессе возврата своего DBAPI-соединения в пул соединений.

    Сценарий заключался в том, что хук Connection уже выполнил .rollback() на своем DBAPI-соединении в процессе возврата соединения в пул, где он инструктировал пул соединений отказаться от выполнения собственного «сброса», чтобы сэкономить на дополнительном вызове метода. Однако это не позволяло использовать пользовательские схемы сброса пула в рамках данного хука, поскольку такие хуки по определению выполняют нечто большее, чем просто вызов .rollback(), и должны вызываться при любых обстоятельствах. Это была регрессия, появившаяся в версии 1.4.

    В версии 1.4 функция PoolEvents.checkin() по-прежнему используется в качестве альтернативного крючка событий для пользовательских реализаций «сброса». В версии 2.0 появится улучшенная версия PoolEvents.reset(), которая будет вызываться для дополнительных сценариев, таких как завершение asyncio-соединений, а также ей будет передаваться контекстная информация о сбросе, что позволит реализовать схемы «пользовательского сброса соединений», которые могут по-разному реагировать на различные сценарии сброса.

    This change is also backported to: 1.4.43

    References: #8717

sql

  • [sql] [bug]

    Исправлена проблема, из-за которой конструкция literal_column() не могла корректно работать в контексте конструкции Select, а также в других потенциальных местах генерации «анонимных меток», если литеральное выражение содержало символы, которые могли помешать строкам форматирования, например, открытую круглую скобку, что связано с особенностями реализации структуры «анонимная метка».

    This change is also backported to: 1.4.43

    References: #8724

typing

  • [typing] [bug]

    Исправлены различные опечатки в пакетах engine и async engine.

postgresql

  • [postgresql] [feature]

    В новый объект данных Range добавлены новые методы Range.contains() и Range.contained_by(), которые повторяют поведение операторов PostgreSQL @> и <@, а также методов операторов SQL comparator_factory.contains() и comparator_factory.contained_by(). Pull request любезно предоставлен Леле Гайфаксом.

    References: #8706

  • [postgresql] [usecase]

    Усовершенствован новый подход к объектам диапазона, описанный в Новая поддержка RANGE / MULTIRANGE и изменения для бэкендов PostgreSQL, с учетом специфических для драйвера объектов диапазона и мультидиапазона, что позволяет лучше использовать их как в устаревшем коде, так и при передаче результатов из необработанных наборов результатов SQL обратно в новые выражения диапазона или мультидиапазона.

    References: #8690

mssql

  • [mssql] [bug]

    Исправлена проблема с Inspector.has_table(), которая при использовании к временной таблице диалекта SQL Server приводила к ошибке на некоторых вариантах Azure из-за лишнего запроса к информационной схеме, который не поддерживается на этих версиях сервера. Pull request любезно предоставлен Майком Барри.

    This change is also backported to: 1.4.43

    References: #8714

  • [mssql] [bug] [reflection]

    Исправлена проблема с Inspector.has_table(), которая при использовании против представления с диалектом SQL Server ошибочно возвращала False, что связано с регрессией в серии 1.4, удалившей поддержку этой функции на SQL Server. В серии 2.0, использующей другую архитектуру отражения, эта проблема отсутствует. Добавлена тестовая поддержка, чтобы убедиться, что has_table() продолжает работать в соответствии со спецификацией, касающейся представлений.

    This change is also backported to: 1.4.43

    References: #8700

oracle

  • [oracle] [bug]

    Исправлена проблема, при которой имена связанных параметров, в том числе автоматически получаемые из аналогичных по названию столбцов базы данных, содержащие символы, обычно требующие кавычек в Oracle, не экранировались при использовании «расширяющих параметров» в диалекте Oracle, что приводило к ошибкам выполнения. Обычное «кавычки» для связанных параметров, используемые диалектом Oracle, в архитектуре «расширяющих параметров» не применяются, поэтому вместо них используется экранирование для большого диапазона символов, теперь с использованием списка символов/эскейпов, специфичных для Oracle.

    This change is also backported to: 1.4.43

    References: #8708

  • [oracle] [bug]

    Исправлена проблема, при которой представление nls_session_parameters, запрашиваемое при первом подключении для получения десятичного символа по умолчанию, могло быть недоступно в зависимости от режимов подключения Oracle, что приводило к возникновению ошибки. Подход к определению десятичного символа был упрощен и теперь проверяется непосредственно десятичное значение, а не чтение системных представлений, что работает на любом бэкенде/драйвере.

    This change is also backported to: 1.4.43

    References: #8744

2.0.0b2

Released: October 20, 2022

orm

  • [orm] [bug]

    Убрано предупреждение, выдаваемое при использовании ORM-совместимых update/delete относительно оценки столбцов по имени, впервые добавленное в #4073; это предупреждение фактически закрывает сценарий, в котором в противном случае может быть выдано неверное значение Python для атрибута, сопоставленного ORM, в зависимости от того, каким является реальный столбец, поэтому этот устаревший случай удален. В версии 2.0 для обновления/удаления с поддержкой ORM используется значение «auto» для «synchronize_session», которое должно автоматически выполнять правильные действия для любого заданного выражения UPDATE.

    References: #8656

orm declarative

  • [orm] [declarative] [usecase]

    Добавлена поддержка отображения классов, которые также являются подклассами Generic, для указания их в виде объекта GenericAlias (например, MyClass[str]) в операторах и вызовах inspect().

    References: #8665

  • [orm] [declarative] [bug]

    Класс DeclarativeBase улучшен таким образом, что в сочетании с другими миксинами, например MappedAsDataclass, порядок следования классов может быть любым.

    References: #8665

  • [orm] [declarative] [bug]

    Исправлена ошибка в новых типизированных декларативных отображениях ORM, когда в аннотации типа для отношения «многие-к-одному» не была реализована возможность использования Optional[MyClass] или аналогичных форм, таких как MyClass | None, что приводило к ошибкам. Документация для этого случая использования также была добавлена в документацию по конфигурации отношений.

    References: #8668

  • [orm] [declarative] [bug]

    Исправлена проблема с новой функцией отображения классов данных, когда аргументы, передаваемые в API классов данных, иногда могли быть неправильно упорядочены при работе с миксинами, переопределяющими объявления mapped_column(), что приводило к проблемам с инициализаторами.

    References: #8688

sql

  • [sql] [bug] [regression]

    Исправлена ошибка в новой функции «insertmanyvalues», когда INSERT, включающий в себя подзапрос с bindparam() внутри, не мог корректно отображаться в формате «insertmanyvalues». В наибольшей степени это затрагивало psycopg2, так как «insertmanyvalues» используется в этом драйвере безусловно.

    References: #8639

typing

  • [typing] [bug]

    Исправлена проблема, при которой в строгом режиме pylance выдавалось сообщение «instance variable overrides class variable» при использовании метода для определения __tablename__, __mapper_args__ или __table_args__.

    References: #8645

  • [typing] [bug]

    Исправлена проблема типизации, при которой строгий режим pylance сообщал о «частично неизвестном» типе данных для конструкции mapped_column().

    References: #8644

mssql

  • [mssql] [bug]

    Исправлена регрессия, вызванная изменением SQL Server pyodbc #8177, где теперь по умолчанию используется setinputsizes(); для VARCHAR это не удается, если размер символа превышает 4000 (или 2000, в зависимости от данных) символов, поскольку входящий тип данных - NVARCHAR, который имеет ограничение в 4000 символов, несмотря на то, что VARCHAR может работать с неограниченным количеством символов. Дополнительная информация о типизации, специфичная для pyodbc, теперь передается в setinputsizes(), если размер типа данных > 2000 символов. Это изменение распространяется и на тип JSON, который также был подвержен этой проблеме при сериализации больших JSON-файлов.

    References: #8661

  • [mssql] [bug]

    Конструкция Sequence возвращается к поведению DDL до версии 1.4, когда создание Sequence без дополнительных аргументов приводит к появлению простой инструкции CREATE SEQUENCE без дополнительных параметров для «начального значения». В любом случае, для большинства бэкендов именно так все и происходило; как бы то ни было, для MS SQL Server значение по умолчанию для этой базы данных равно -2**63; чтобы предотвратить действие этого в общем-то непрактичного значения по умолчанию на SQL Server, необходимо указать параметр Sequence.start. Поскольку использование Sequence необычно для SQL Server, который в течение многих лет стандартизировался на IDENTITY, можно надеяться, что это изменение окажет минимальное влияние.

    References: #7211

2.0.0b1

Released: October 13, 2022

general

  • [general] [changed]

    В результате миграции кодовой базы были удалены все модели поведения и архитектуры, существовавшие до версии 2.0, которые ранее были отмечены как устаревшие и подлежащие удалению в версии 2.0, включая, но не ограничиваясь ими:

    • удален весь код Python 2, минимальной версией теперь является Python 3.7

    • Engine и Connection теперь используют новый стиль работы 2.0, который включает в себя «autobegin», удален автокоммит на уровне библиотеки, удалены субтранзакции и «разветвленные» соединения

    • Объекты-результаты используют поведение в стиле 2.0; Row является полностью именованным кортежем без поведения «отображения», для поведения «отображения» используйте RowMapping

    • Из SQLAlchemy удалена вся архитектура кодирования/декодирования Unicode. Все современные реализации DBAPI поддерживают Unicode прозрачно благодаря Python 3, поэтому функция convert_unicode, а также связанные с ней механизмы поиска байтовых строк в DBAPI cursor.description и т.д. были удалены.

    • Атрибут .bind и параметр MetaData, Table, а также все элементы DDL/DML/DQL, которые ранее могли ссылаться на «связанный движок»

    • Автономная функция sqlalchemy.orm.mapper() удалена, все классическое отображение должно осуществляться через метод registry.map_imperatively() из registry.

    • Метод Query.join() больше не принимает строки для имен отношений; давно задокументированный подход использования Class.attrname для целей соединения теперь является стандартным.

    • Query.join() больше не принимает аргументы «aliased» и «from_joinpoint»

    • Query.join() больше не принимает цепочки из нескольких целей присоединения в одном вызове метода.

    • Query.from_self(), Query.select_entity_from() и Query.with_polymorphic() удалены.

    • Параметр relationship.cascade_backrefs теперь должен оставаться по умолчанию False; каскад save-update больше не каскадирует по обратной ссылке.

    • параметр Session.future всегда должен быть установлен в значение True. Шаблоны транзакций в стиле 2.0 для Session теперь действуют всегда.

    • Опции загрузчика больше не принимают строки для имен атрибутов. Давно документированный подход использования Class.attrname для целей опций загрузчика теперь является стандартным.

    • Устаревшие формы select() удалены, включая select([cols]), «whereclause» и параметры ключевых слов some_table.select().

    • Устранены устаревшие методы «in-place mutator» на Select, такие как append_whereclause(), append_order_by() и т.д.

    • Удален очень старый модуль «dbapi_proxy», который в самых ранних версиях SQLAlchemy использовался для создания прозрачного пула соединений над сырым DBAPI-соединением.

    References: #7257

  • [general] [changed]

    Метод Query.instances() является устаревшим. Поведенческий контракт этого метода, заключающийся в том, что он может итерировать объекты через произвольные наборы результатов, давно устарел и больше не тестируется. Произвольные операторы могут возвращать объекты, используя такие конструкции, как :meth`.Select.from_statement` or aliased().

platform

  • [platform] [feature]

    Расширения SQLAlchemy на языке C были заменены новыми реализациями, написанными на языке Cython. Как и для предыдущих расширений на языке C, на pypi доступны предварительно собранные файлы wheel для широкого спектра платформ, так что сборка для распространенных платформ не представляет проблемы. Для пользовательских сборок python setup.py build_ext работает как и раньше, требуя лишь дополнительной установки Cython. pyproject.toml теперь также является частью исходного кода, что позволит установить правильные зависимости сборки при использовании pip.

    References: #7256

  • [platform] [change]

    Сборка и установка исходных текстов SQLAlchemy теперь включает файл pyproject.toml для полной поддержки PEP 517.

    References: #7311

orm

  • [orm] [feature] [sql]

    Во все включенные диалекты, поддерживающие RETURNING, добавлена новая функция «insertmanyvalues». Это обобщение функции «fast executemany», впервые представленной для драйвера psycopg2 в версии 1.4 ORM Пакетные вставки с psycopg2 теперь в большинстве случаев выполняют пакетные операции с RETURNING, которая позволяет ORM пакетно объединять операторы INSERT в гораздо более эффективную структуру SQL, сохраняя при этом возможность получать новые значения первичного ключа и значения по умолчанию SQL с помощью RETURNING.

    Теперь эта возможность распространяется на многие диалекты, поддерживающие конструкцию RETURNING вместе с несколькими VALUES для INSERT, включая все драйверы PostgreSQL, SQLite, MariaDB, MS SQL Server. Отдельно такую же возможность получает диалект Oracle, используя собственные функции cx_Oracle или OracleDB.

    References: #6047

  • [orm] [feature]

    Добавлен новый параметр AttributeEvents.include_key, который будет включать в себя ключ словаря или списка для таких операций, как __setitem__() (например, obj[key] = value) и __delitem__() (например, del obj[key]), используя новый параметр-ключ «key» или «keys», в зависимости от события, например, AttributeEvents.append.key, AttributeEvents.bulk_replace.keys. Это позволяет обработчикам событий учитывать ключ, который был передан операции, и особенно важно для словарных операций, работающих с MappedCollection.

    References: #8375

  • [orm] [feature]

    Добавлен новый параметр Operators.op.python_impl, доступный из Operators.op(), а также при непосредственном использовании конструктора custom_op, который позволяет предоставлять вместе с пользовательским SQL-оператором функцию оценки на языке Python. Эта оценочная функция становится реализацией, используемой при использовании объекта operator, когда в качестве операндов с обеих сторон используются обычные объекты Python, и, в частности, совместима с опцией synchronize_session='evaluate', используемой с Операции INSERT, UPDATE и DELETE с поддержкой ORM.

    References: #3162

  • [orm] [feature]

    В Session (и, соответственно, в AsyncSession) появилась новая функциональность отслеживания состояния, которая позволяет проактивно отлавливать любые неожиданные изменения состояния, происходящие по мере выполнения того или иного транзакционного метода. Это позволит в ситуациях, когда Session используется небезопасным для потоков образом, когда крючки событий и т.п. могут вызывать неожиданные методы внутри операций, а также в других ситуациях параллелизма, таких как asyncio или gevent, выдавать информационное сообщение при первом незаконном доступе, а не проходить молча, приводя к вторичным сбоям из-за того, что Session находится в недопустимом состоянии.

    References: #7433

  • [orm] [feature]

    Конструкция отображения composite() теперь поддерживает автоматическое разрешение значений при использовании с Python dataclass; метод __composite_values__() больше не нужно реализовывать, так как этот метод получается в результате проверки класса данных.

    Кроме того, классы, отображаемые с помощью composite, теперь поддерживают операции упорядоченного сравнения, например <, >= и т.д.

    Примеры смотрите в новой документации по адресу Типы составных колонн.

  • [orm] [feature]

    В опции загрузчика selectinload() и immediateload() добавлена экспериментальная возможность selectinload.recursion_depth / immediateload.recursion_depth, которая позволяет одной опции загрузчика автоматически осуществлять рекурсию по самореферентным связям. Устанавливается в целое число, указывающее глубину, а также может быть установлено в -1, чтобы указать на продолжение загрузки до тех пор, пока не будет найдено больше ни одного уровня в глубину. Значительные внутренние изменения в selectinload() и immediateload() позволяют этой возможности работать, продолжая корректно использовать кэш компиляции, а также не использовать произвольную рекурсию, так что поддерживается любой уровень глубины (хотя при этом будет выдаваться такое количество запросов). Это может быть полезно для самореферентных структур, которые должны загружаться полностью с нетерпением, например, при использовании asyncio.

    Предупреждение выдается также при соединении опций загрузчика с произвольной длиной (то есть без использования новой опции recursion_depth), когда в загрузке связанных объектов обнаруживается чрезмерная глубина рекурсии. Такая операция продолжает использовать огромные объемы памяти и работает крайне плохо; для защиты кэша от переполнения произвольными утверждениями при обнаружении этого условия кэш отключается.

    References: #8126

  • [orm] [feature]

    Добавлен новый параметр Session.autobegin, который при установке значения False не позволит методу Session начать транзакцию неявно. Для продолжения операций необходимо сначала явно вызвать метод Session.begin(), иначе будет выдана ошибка, если какая-либо операция в противном случае началась бы автоматически. Эта опция может быть использована для создания «безопасного» Session, который не будет неявно начинать новые транзакции.

    В рамках этого изменения также добавлена новая переменная состояния origin, которая может быть полезна для кода обработки событий, чтобы знать о происхождении конкретного SessionTransaction.

    References: #6928

  • [orm] [feature]

    Декларативным миксинам, использующим объекты Column, содержащие ссылки ForeignKey, больше не нужно использовать declared_attr() для достижения такого отображения; объект ForeignKey копируется вместе с самим Column при применении колонки к объявленному отображению.

  • [orm] [usecase]

    В опцию загрузчика load_only() добавлен параметр load_only.raiseload, чтобы выгружаемые атрибуты могли иметь поведение «raise», а не ленивую загрузку. Ранее не было возможности сделать это с помощью параметра load_only() напрямую.

  • [orm] [change]

    Для более удобного использования явной типизации имена некоторых ORM-конструкций, которые обычно строятся внутри, но, тем не менее, иногда проявляются при обмене сообщениями, а также при типизации, были изменены на более лаконичные имена, которые также соответствуют имени функции-конструктора (с другим регистром), во всех случаях сохраняя псевдонимы на старые имена на обозримое будущее:

    • RelationshipProperty становится псевдонимом для основного имени Relationship, которое строится, как всегда, из функции relationship()

    • SynonymProperty становится псевдонимом для основного имени Synonym, построенного, как всегда, на основе функции synonym()

    • CompositeProperty становится псевдонимом для основного имени Composite, построенного, как всегда, на основе функции composite()

  • [orm] [change]

    Для согласованности с известной концепцией ORM Mapped названия коллекций, ориентированных на словари, attribute_mapped_collection(), column_mapped_collection() и MappedCollection, изменены на attribute_keyed_dict(), column_keyed_dict() и KeyFuncDict, причем словосочетание «dict» используется для того, чтобы свести к минимуму путаницу с термином «mapped». Старые имена останутся на неопределенный срок, и их удаление не планируется.

    References: #8608

  • [orm] [bug]

    Теперь все объекты Result будут последовательно вызывать ResourceClosedError, если они используются после жесткого закрытия, которое включает в себя «жесткое закрытие», возникающее после вызова методов «одной строки или значения», таких как Result.first() и Result.scalar(). Такое поведение уже было характерно для наиболее распространенного класса объектов результатов, возвращаемых при выполнении операторов Core, т.е. для объектов, основанных на CursorResult, поэтому такое поведение не является новым. Однако это изменение было расширено для того, чтобы должным образом учесть «фильтрацию» ORM-объектов, возвращаемых при использовании ORM-запросов в стиле 2.0, которые ранее вели себя в стиле «мягкого закрытия», возвращая пустые результаты, или вообще не «мягко закрывались» и продолжали выдавать результаты из базового курсора.

    В рамках этого изменения в базовый класс Result был добавлен Result.close() и реализован для реализаций фильтрованных результатов, используемых ORM, чтобы можно было вызвать метод CursorResult.close() на базовом CursorResult, когда используется опция выполнения yield_per, чтобы закрыть курсор на стороне сервера до того, как будут извлечены оставшиеся результаты ORM. Эта возможность уже была доступна для наборов результатов Core, но данное изменение делает ее доступной и для результатов ORM в стиле 2.0.

    This change is also backported to: 1.4.27

    References: #7274

  • [orm] [bug]

    Исправлена проблема, при которой метод registry.map_declaratively() возвращал внутренний объект «mapper config», а не объект Mapper, как указано в документации к API.

  • [orm] [bug]

    Исправлена регрессия производительности, проявившаяся как минимум в версии 1.3, если не раньше (спустя некоторое время после 1.0), когда при загрузке отложенных колонок, явно отображенных с помощью defer(), в отличие от не отложенных колонок, срок действия которых истек, из объединенного подкласса наследования не использовался «оптимизированный» запрос, который запрашивал только непосредственную таблицу, содержащую невыгруженные колонки, а выполнялся полный ORM-запрос, создающий JOIN для всех базовых таблиц, что не требуется при загрузке колонок только из подкласса.

    References: #7463

  • [orm] [bug]

    Внутренние компоненты объекта Load и связанных с ним шаблонов стратегий загрузчика были в основном переписаны, чтобы воспользоваться тем фактом, что теперь поддерживаются только пути, связанные с атрибутами, а не строки. Эта переработка позволит в дальнейшем более просто решать новые задачи и тонкие проблемы в системе стратегий загрузчика.

    References: #6986

  • [orm] [bug]

    Внесено улучшение в набор опций стратегии «отложенная» / «load_only», при котором, если определенный объект загружается из двух различных логических путей в рамках одного запроса, атрибуты, которые были настроены хотя бы в одном из вариантов на заполнение, будут заполнены во всех случаях, даже если в других путях загрузки этого же объекта данная опция не была установлена. ранее это было основано на случайности того, какой «путь» обратился к объекту первым.

    References: #8166

  • [orm] [bug]

    Исправлена проблема, связанная с UPDATE с поддержкой ORM, когда оператор создается в подклассе с объединенным наследованием и обновляет только локальные столбцы таблицы, когда стратегия синхронизации «fetch» не приводила к корректной формуле RETURNING для баз данных, использующих RETURNING для синхронизации fetch. Также скорректирована стратегия, используемая для RETURNING в операторах UPDATE FROM и DELETE FROM.

    References: #8344

  • [orm] [bug] [asyncio]

    Удалены неиспользуемые аргументы **kw из begin и begin_nested. Эти kw не используются и, по-видимому, были добавлены в API ошибочно.

    References: #7703

  • [orm] [bug]

    Изменен метод доступа к атрибутам attribute_mapped_collection() и column_mapped_collection() (теперь они называются attribute_keyed_dict() и column_keyed_dict()), используемый при заполнении словаря, для подтверждения того, что значение данных в объекте, используемом в качестве ключа словаря, действительно присутствует, а не используется «None» из-за того, что атрибут никогда не был назначен. Это используется для предотвращения ошибочного использования None в качестве ключа при назначении через обратную ссылку, когда атрибут «key» объекту еще не назначен.

    Поскольку возникающая здесь ошибка является преходящим состоянием, которое обычно не сохраняется в базе данных, и легко возникает в конструкторе класса на основе порядка присваивания параметров, вполне возможно, что во многих приложениях такое поведение уже присутствует, и оно молчаливо передается. Для того чтобы учесть особенности приложений, в которых теперь возникает такая ошибка, к параметрам attribute_keyed_dict() и column_keyed_dict() добавлен новый параметр attribute_keyed_dict.ignore_unpopulated_attribute, который вместо этого заставляет пропустить ошибочное присваивание обратной ссылки.

    References: #8372

  • [orm] [bug]

    Добавлен новый параметр AbstractConcreteBase.strict_attrs в декларативный класс миксина AbstractConcreteBase. В результате использования этого параметра область действия атрибутов подклассов корректно ограничивается подклассом, в котором объявлен каждый атрибут, а не как раньше, когда все атрибуты всей иерархии применяются к базовому «абстрактному» классу. В результате получается более чистое и корректное отображение, в котором подклассы больше не имеют неиспользуемых атрибутов, относящихся только к классам-братьям. По умолчанию для этого параметра установлено значение False, которое оставляет прежнее поведение без изменений; это сделано для поддержки существующего кода, который явно использует эти атрибуты в запросах. Для перехода к новому подходу следует по мере необходимости применять явные атрибуты к абстрактному базовому классу.

    References: #8403

  • [orm] [bug]

    Поведение defer() в отношении столбцов первичного ключа и «полиморфного дискриминатора» изменено таким образом, что эти столбцы больше не могут быть отложены ни явно, ни при использовании подстановочного символа, такого как defer('*'). Ранее отсрочка с использованием подстановочного знака не загружала PK/полиморфные столбцы, что приводило к ошибкам во всех случаях, поскольку ORM использует эти столбцы для создания идентификаторов объектов. Поведение явной отсрочки столбцов первичного ключа не изменилось, так как эти отсрочки уже игнорировались неявно.

    References: #7495

  • [orm] [bug]

    Исправлена ошибка в поведении параметра Mapper.eager_defaults, в результате которой выражения SQL по умолчанию или onupdate на стороне клиента, находящиеся только в определении таблицы, будут вызывать операцию выборки с использованием RETURNING или SELECT, когда ORM выдает INSERT или UPDATE для строки. Ранее только значения по умолчанию на стороне сервера, установленные как часть DDL таблицы, и/или выражения onupdate на стороне сервера вызывали такую выборку, даже если выражения SQL на стороне клиента были включены при выводе выборки.

    References: #7438

engine

  • [engine] [feature]

    Событие DialectEvents.handle_error() теперь перенесено в набор DialectEvents из набора EngineEvents и теперь участвует в событии «pre ping» пула соединений для тех диалектов, которые используют коды разъединения для определения наличия базы данных. Это позволяет конечному пользователю изменять состояние «pre ping». Обратите внимание, что это не относится к диалектам, содержащим собственный метод «ping», например, к psycopg2 или большинству диалектов MySQL.

    References: #5648

  • [engine] [feature]

    Крючки событий ConnectionEvents.set_connection_execution_options() и ConnectionEvents.set_engine_execution_options() теперь позволяют модифицировать заданный словарь опций на месте, при этом новое содержимое будет получено в качестве конечных опций выполнения, с которыми нужно будет работать. Ранее модификация словаря на месте не поддерживалась.

  • [engine] [usecase]

    Обобщен параметр create_engine.isolation_level на базовый диалект, чтобы он больше не зависел от наличия отдельных диалектов. Этот параметр устанавливает значение «уровня изоляции» для всех новых соединений с базой данных сразу после их создания пулом соединений, после чего это значение остается установленным и не сбрасывается при каждой проверке.

    Параметр create_engine.isolation_level по своей функциональности эквивалентен использованию параметра Engine.execution_options.isolation_level через Engine.execution_options() для настройки всего движка. Разница заключается в том, что в первом случае уровень изоляции назначается один раз при создании соединения, а во втором - устанавливается и сбрасывается при каждой проверке соединения.

    References: #6342

  • [engine] [change]

    Небольшие изменения в API, касающиеся движков и диалектов:

    • Методам Dialect.set_isolation_level(), Dialect.get_isolation_level(), :meth: dialect всегда будет передаваться необработанное соединение DBAPI

    • Классы Connection и Engine больше не имеют общего базового суперкласса Connectable, который был удален.

    • Добавлен новый интерфейсный класс PoolProxiedConnection - это публичный интерфейс для знакомого класса _ConnectionFairy, который, тем не менее, является частным классом.

    References: #7122

  • [engine] [bug] [regression]

    Исправлена регрессия, при которой метод CursorResult.fetchmany() не приводил к автозакрытию курсора на стороне сервера (т.е. при использовании stream_results или yield_per, ориентированных на Core или ORM), когда результаты были полностью исчерпаны.

    This change is also backported to: 1.4.27

    References: #7274

  • [engine] [bug]

    В будущих Engine исправлена проблема, когда вызов Engine.begin() и вход в контекстный менеджер не закрывал соединение, если сама операция BEGIN по какой-то причине не выполнялась, например, обработчик события вызывал исключение; этот вариант использования не удалось протестировать для будущей версии движка. Обратите внимание, что «будущие» контекстные менеджеры, обрабатывающие блоки begin() в Core и ORM, не выполняют операцию «BEGIN» до тех пор, пока не будут введены контекстные менеджеры. Это отличается от старой версии, в которой операция «BEGIN» выполняется заранее.

    This change is also backported to: 1.4.27

    References: #7272

  • [engine] [bug]

    Теперь QueuePool игнорирует max_overflow при pool_size=0, делая пул неограниченным во всех случаях.

    References: #8523

  • [engine] [bug]

    Для повышения безопасности объект URL теперь по умолчанию использует обфускацию пароля при вызове str(url). Для структуризации URL с паролем в открытом виде можно использовать URL.render_as_string(), передавая параметр URL.render_as_string.hide_password в виде False. Спасибо нашим соавторам за этот pull request.

    References: #8567

  • [engine] [bug]

    Метод Inspector.has_table() теперь будет последовательно проверять наличие представлений с заданным именем, а также таблиц. Ранее такое поведение зависело от диалекта: PostgreSQL, MySQL/MariaDB и SQLite поддерживали его, а Oracle и SQL Server не поддерживали. Диалекты сторонних разработчиков также должны стремиться к тому, чтобы их метод Inspector.has_table() выполнял поиск представлений, а также таблиц для заданного имени.

    References: #7161

  • [engine] [bug]

    Исправлена проблема в методе Result.columns(), когда вызов Result.columns() с единственным индексом в некоторых случаях, особенно в случаях с объектами результатов ORM, мог привести к тому, что Result выдавал скалярные объекты, а не объекты Row, как если бы был вызван метод Result.scalars(). В SQLAlchemy 1.4 при таком сценарии выдается предупреждение о том, что поведение изменится в SQLAlchemy 2.0.

    References: #7953

  • [engine] [bug]

    Передача объекта DefaultGenerator, такого как Sequence, в метод Connection.execute() является устаревшей, поскольку этот метод типизирован как возвращающий объект CursorResult, а не простое скалярное значение. Вместо него следует использовать метод Connection.scalar(), который был переработан с новыми внутренними кодовыми путями, чтобы можно было вызывать SELECT для объектов генерации по умолчанию, не проходя через метод Connection.execute().

  • [engine] [removed]

    Из create_engine() удален ранее устаревший параметр case_sensitive, который влиял только на поиск строковых имен столбцов в строках набора результатов только для Core; на поведение ORM он не влиял. Эффективное поведение параметра case_sensitive, на который ссылается , остается на уровне значения по умолчанию True, что означает, что имена строк, найденные в row._mapping, будут соответствовать регистру, как и любое другое отображение Python.

    Заметим, что параметр case_sensitive никак не связан с общей темой контроля чувствительности к регистру, кавычек и «нормализации имен» (т.е. преобразования для баз данных, считающих все слова в верхнем регистре нечувствительными к регистру) для имен идентификаторов DDL, которая остается нормальной основной особенностью SQLAlchemy.

  • [engine] [removed]

    Удален устаревший и устаревший пакет sqlalchemy.databases. Вместо него следует использовать sqlalchemy.dialects.

    References: #7258

  • [engine] [deprecations]

    Параметр create_engine.implicit_returning устарел только для функции create_engine(); параметр остается доступным для объекта Table. Этот параметр изначально предназначался для включения функции «неявного возврата» в SQLAlchemy, когда она только разрабатывалась, и не был включен по умолчанию. При современном использовании нет причин отключать этот параметр, и было замечено, что он вызывает путаницу, поскольку снижает производительность и затрудняет получение ORM недавно вставленных серверных значений по умолчанию. Параметр остается доступным на Table специально для тех случаев на уровне базы данных, которые делают RETURNING невыполнимым, единственным примером в настоящее время является ограничение SQL Server на то, что INSERT RETURNING не может быть использован в таблице, на которую установлены триггеры INSERT.

    References: #6962

sql

  • [sql] [feature]

    В дополнение к существующим операторам композиции LIKE ColumnOperators.contains(), ColumnOperators.startswith() и т.д. добавлены давно востребованные операторы строк ColumnOperators.icontains(), ColumnOperators.istartswith(), ColumnOperators.iendswith(), которые создают композиции LIKE с учетом регистра (с использованием функции ILIKE в PostgreSQL и функции LOWER() во всех остальных бэкендах). Огромная благодарность Матиасу Мартинесу Ребори за кропотливую и полную работу по реализации этих новых методов.

    References: #3482

  • [sql] [feature]

    Добавлен новый синтаксис к коллекции FromClause.c на всех объектах FromClause, позволяющий передавать кортежи ключей в __getitem__(), а также поддержка конструкции select() для непосредственной работы с полученной кортежеподобной коллекцией, что позволяет использовать синтаксис select(table.c['a', 'b', 'c']). Возвращаемая подколлекция сама является ColumnCollection, которая также непосредственно потребляется select() и другими подобными средствами.

    См.также

    Установить

    References: #8285

  • [sql] [feature]

    Добавлен новый бэкенд-агностический тип данных Uuid, обобщенный из диалектов PostgreSQL и ставший основным типом, а также перенесенный UUID из диалекта PostgreSQL. Тип данных SQL Server UNIQUEIDENTIFIER также стал типом данных, работающим с UUID. Спасибо Тревору Гроссу за помощь в этом вопросе.

    References: #7212

  • [sql] [feature]

    В пространство имен базового модуля sqlalchemy. добавлены типы данных Double, DOUBLE, DOUBLE_PRECISION для явного использования двойной/двухкратной точности, а также общие типы данных «double». Используйте Double для общей поддержки, которая будет преобразовываться в DOUBLE/DOUBLE PRECISION/FLOAT по мере необходимости для различных бэкендов.

    References: #5465

  • [sql] [usecase]

    Изменена механика компиляции конструкции Insert таким образом, что значение столбца «autoincrement primary key» будет получено через cursor.lastrowid или RETURNING, даже если оно присутствует в наборе параметров или в методе Insert.values() в виде простого связанного значения, для однорядных операторов INSERT на определенных бэкендах, которые, как известно, генерируют автоинкрементные значения даже при явном передаче NULL. Это восстанавливает поведение, которое было в серии 1.3 как для случая использования отдельного набора параметров, так и для Insert.values(). В версии 1.4 поведение набора параметров непреднамеренно изменилось и перестало выполняться, но метод Insert.values() по-прежнему получал автоинкрементные значения вплоть до версии 1.4.21, в которой метод #6770 снова непреднамеренно изменил поведение, поскольку этот вариант использования никогда не рассматривался.

    Теперь поведение определено как «рабочее» для случая, когда такие базы данных, как SQLite, MySQL и MariaDB, будут игнорировать явное значение первичного ключа NULL и, тем не менее, вызывать генератор автоинкремента.

    References: #7998

  • [sql] [usecase]

    Добавлено модифицированное отображение ISO-8601 (т.е. ISO-8601 с T, преобразованным в пробел) при использовании literal_binds с SQL-компиляторами, предоставляемыми диалектами PostgreSQL, MySQL, MariaDB, MSSQL, Oracle. Для Oracle формат ISO оборачивается внутрь соответствующего вызова функции TO_DATE(). Ранее для компиляции в зависимости от диалекта этот рендеринг не был реализован.

    References: #5052

  • [sql] [usecase]

    В HasCTE.add_cte() добавлен новый параметр HasCTE.add_cte.nest_here, который будет «вложен» в данный CTE на уровне родительского оператора. Этот параметр эквивалентен использованию параметра HasCTE.cte.nesting, но в некоторых сценариях может быть более интуитивным, поскольку позволяет задавать атрибут вложенности одновременно с явным уровнем CTE.

    Метод HasCTE.add_cte() также принимает несколько объектов CTE.

    References: #7759

  • [sql] [bug]

    Клаузы FROM, установленные в конструкции select() при использовании метода Select.select_from(), теперь будут отображаться первыми в клаузе FROM рендерируемого SELECT, что позволяет сохранить порядок клауз, переданный в метод Select.select_from(), и не зависеть от наличия этих клауз в других частях запроса. Если другие элементы Select также генерируют предложения FROM, например, предложение columns или предложение WHERE, то они будут отображаться после предложений, переданных Select.select_from(), если они не были явно переданы в Select.select_from(). Это улучшение полезно в тех случаях, когда конкретная база данных формирует желаемый план запроса на основе определенного порядка следования предложений FROM и позволяет полностью контролировать порядок следования предложений FROM.

    References: #7888

  • [sql] [bug]

    Параметр Enum.length, задающий длину столбца VARCHAR для неродных типов перечислений, теперь безоговорочно используется при создании DDL для типа данных VARCHAR, в том числе и при установке параметра Enum.native_enum в значение True для целевых бэкендов, продолжающих использовать VARCHAR. Ранее в этом случае параметр ошибочно игнорировался. Предупреждение, выдававшееся ранее для этого случая, теперь удалено.

    References: #7791

  • [sql] [bug]

    Определение типа на месте для целых чисел Python, как это происходит с выражением literal(25), теперь также будет применять адаптацию на основе значений для больших целых чисел Python, где определяемый тип данных будет BigInteger, а не Integer. Это позволяет использовать такие диалекты, как asyncpg, который как передает драйверу неявную информацию о типе, так и чувствителен к числовым масштабам.

    References: #7909

  • [sql] [bug]

    Добавлены параметры if_exists и if_not_exists для всех конструкций «Create» / «Drop», включая CreateSequence, DropSequence, CreateIndex, DropIndex и т.д., позволяющие выводить общие фразы «IF EXISTS» / «IF NOT EXISTS» в DDL. Pull request любезно предоставлен Jesse Bakker.

    References: #7354

  • [sql] [bug]

    Улучшено построение бинарных выражений SQL, что позволяет использовать очень длинные выражения против одного и того же ассоциативного оператора без специальных действий, чтобы избежать большого объема памяти и избыточной глубины рекурсии. Определенная бинарная операция A op B теперь может быть объединена с другим элементом op C, и полученная структура будет «уплощена», так что представление, а также компиляция SQL не требуют рекурсии.

    Одним из следствий этого изменения является то, что выражения конкатенации строк, использующие функции SQL, получаются «плоскими», например, MySQL теперь будет выводить concat('x', 'y', 'z', ...)`, а не вложенные друг в друга двухэлементные функции типа concat(concat('x', 'y'), 'z'). Сторонние диалекты, переопределяющие оператор конкатенации строк, должны будут реализовать новый метод def visit_concat_op_expression_clauselist() в дополнение к существующему методу def visit_concat_op_binary().

    References: #7744

  • [sql] [bug]

    Реализована полная поддержка операций «truediv» и «floordiv» с использованием операторов «/» и «//». Теперь операция «truediv» между двумя выражениями, использующими Integer, считает результат Numeric, а компиляция на уровне диалекта приведет правый операнд к числовому типу в зависимости от диалекта, чтобы обеспечить truediv. Для floordiv также добавлено преобразование для тех баз данных, которые по умолчанию не используют floordiv (MySQL, Oracle), и в этом случае приводится функция FLOOR(), а также для случаев, когда правый операнд не является целым числом (необходимо для PostgreSQL и др.).

    Данное изменение решает проблемы, связанные как с несогласованным поведением оператора деления на различных бэкендах, так и устраняет проблему, когда при целочисленном делении на Oracle не удавалось получить результат из-за некорректных обработчиков типа вывода.

    References: #4926

  • [sql] [bug]

    В компилятор добавлен дополнительный шаг поиска, который будет отслеживать все предложения FROM, являющиеся таблицами, которые могут иметь одно и то же имя, совместно используемое в нескольких схемах, где одна из схем является неявной схемой «по умолчанию»; в этом случае имя таблицы при обращении к этому имени без уточнения схемы будет отображаться анонимным псевдонимом на уровне компилятора, чтобы дезамбигировать эти два (или более) имени. Рассматривался также вариант схемной квалификации обычно неквалифицированного имени с помощью определяемого сервером значения «default schema name», однако этот подход не применим к Oracle, не принимается SQL Server и не работает при наличии нескольких записей в пути поиска PostgreSQL. Проблема столкновения имен, решенная в данной статье, была идентифицирована как влияющая, по крайней мере, на Oracle, PostgreSQL, SQL Server, MySQL и MariaDB.

    References: #7471

  • [sql] [bug]

    Для строковых значений Python, для которых тип SQL определяется из типа значения, в основном при использовании literal(), теперь будет применяться тип String, а не тип данных Unicode, для строковых значений Python, которые тестируются как «ascii only» при использовании Python str.isascii(). Если строка не isascii(), то вместо нее будет привязан тип данных Unicode, который ранее использовался во всех случаях определения строк. Такое поведение применимо только для определения типов данных на месте при использовании ``literal()`` или других контекстов, не имеющих существующего типа данных, чего обычно не происходит при обычных операциях сравнения Column, где тип сравниваемого Column всегда имеет приоритет.

    Использование типа данных Unicode может определять форматирование литеральных строк на таких бэкендах, как SQL Server, где литеральное значение (т.е. использующее literal_binds) будет отображаться как N'<value>', а не как 'value'. Для обычной работы со связанными значениями тип данных Unicode также может иметь значение для передачи значений в DBAPI, опять же в случае SQL Server, драйвер pyodbc поддерживает использование setinputsizes mode, который будет по-разному обрабатывать String и Unicode.

    References: #7551

  • [sql] [bug]

    Теперь array_agg будет устанавливать размерность массива равной 1. Улучшена обработка ARRAY для приема значений None в качестве значения мультимассива.

    References: #7083

schema

  • [schema] [feature]

    Расширение системы «условного DDL», реализованной в классе ExecutableDDLElement (переименованном из DDLElement), для непосредственного использования в конструкциях SchemaItem, таких как Index, ForeignKeyConstraint и т.д., таким образом, условная логика генерации этих элементов включается в процесс генерации DDL по умолчанию. Эта система также может быть реализована в будущем выпуске Alembic для поддержки условных элементов DDL во всех системах управления схемами.

    References: #7631

  • [schema] [usecase]

    В конструкцию DropConstraint добавлен параметр DropConstraint.if_exists, который приводит к добавлению в DDL оператора «IF EXISTS». DDL добавляется к оператору DROP. Эта фраза принимается не всеми базами данных, и операция будет неудачной в базе данных, которая ее не поддерживает, так как в рамках одного DDL-оператора нет аналогичного совместимого запасного варианта. Pull request любезно предоставлен Майком Фидлером.

    References: #8141

  • [schema] [usecase]

    Реализованы крючки событий DDL DDLEvents.before_create(), DDLEvents.after_create(), DDLEvents.before_drop(), DDLEvents.after_drop() для всех объектов SchemaItem, включающих отдельный шаг CREATE или DROP, когда этот шаг вызывается как отдельный SQL-оператор, в том числе для ForeignKeyConstraint, Sequence, Index и ENUM в PostgreSQL.

    References: #8394

  • [schema] [performance]

    Переработан API отражения схем, что позволяет использовать высокопроизводительные пакетные запросы для отражения схем многих таблиц одновременно, используя на порядок меньшее количество запросов. Новые возможности по производительности ориентированы в первую очередь на бэкенды PostgreSQL и Oracle и могут быть применены к любому диалекту, использующему для отражения таблиц запросы SELECT к таблицам системного каталога. Изменения также включают новые возможности API и улучшения поведения объекта Inspector, в том числе согласованное, кэшируемое поведение методов Inspector.has_table(), Inspector.get_table_names() и новые методы Inspector.has_schema() и Inspector.has_index().

    References: #4379

  • [schema] [bug]

    Убраны предупреждения, выдаваемые при отражении индексов или уникальных ограничений, когда параметр Table.include_columns используется для исключения столбцов, которые затем оказываются частью этих ограничений. При использовании параметра Table.include_columns следует ожидать, что результирующая конструкция Table не будет включать ограничения, опирающиеся на опущенные столбцы. Это изменение было внесено в ответ на предложение #8100, которое восстановило Table.include_columns в сочетании с ограничениями внешнего ключа, которые полагаются на опущенные столбцы, когда стало ясно, что следует ожидать исключения таких ограничений.

    References: #8102

  • [schema] [postgresql]

    Добавлена поддержка комментариев к объектам Constraint, включая DDL и reflection; поле добавляется в базовый класс Constraint и соответствующие конструкторы, однако PostgreSQL является единственным бэкендом, поддерживающим эту возможность в настоящее время. См. такие параметры, как ForeignKeyConstraint.comment, UniqueConstraint.comment или CheckConstraint.comment.

    References: #5677

  • [schema] [mariadb] [mysql]

    Добавлена поддержка отраженных опций Partitioning и Sample pages на MySQL и MariaDB. Опции хранятся в таблице dialect options dictionary, поэтому к следующему ключевому слову необходимо добавлять префикс mysql_ или mariadb_ в зависимости от бэкенда. Поддерживаются следующие опции:

    • stats_sample_pages

    • partition_by

    • partitions

    • subpartition_by

    Эти опции также отражаются при загрузке таблицы из базы данных и заполняют таблицу Table.dialect_options. Pull request любезно предоставлен Ramon Will.

    References: #4038

typing

  • [typing] [improvement]

    Метод TypeEngine.with_variant() теперь возвращает копию исходного объекта TypeEngine, а не оборачивает его внутри класса Variant, который фактически удаляется (символ импорта остается для обратной совместимости с кодом, который может тестироваться на наличие этого символа). Хотя предыдущий подход сохранял поведение in-Python, сохранение исходного типа позволяет более четко проверять типы и выполнять отладку.

    TypeEngine.with_variant() также допускает несколько имен диалектов в одном вызове, в частности, это полезно для связанных имен бэкендов, таких как "mysql", "mariadb".

    References: #6980

postgresql

  • [postgresql] [feature]

    Добавлен новый тип данных PostgreSQL DOMAIN, в котором реализовано то же поведение CREATE TYPE / DROP TYPE, что и в PostgreSQL ENUM. Большое спасибо Дэвиду Баумголду за проделанную работу.

    См.также

    DOMAIN

    References: #7316

  • [postgresql] [usecase] [asyncpg]

    Добавлены переопределяемые методы PGDialect_asyncpg.setup_asyncpg_json_codec и PGDialect_asyncpg.setup_asyncpg_jsonb_codec codec, которые решают необходимую задачу регистрации кодеков JSON/JSONB для этих типов данных при использовании asyncpg. Изменения заключаются в том, что методы разбиты на отдельные переопределяемые методы для поддержки сторонних диалектов, которым необходимо изменить или отключить настройку этих кодеков.

    This change is also backported to: 1.4.27

    References: #7284

  • [postgresql] [usecase]

    Добавлена визуализация литеральных типов для типов данных ARRAY и ARRAY. Для общего stringify будут использоваться скобки, например, [1, 2, 3], а для специфичного для PostgreSQL - литерал ARRAY, например, ARRAY[1, 2, 3]. Также учитывается множественная размерность и цитирование.

    References: #8138

  • [postgresql] [usecase]

    Добавлена поддержка многодиапазонных типов PostgreSQL, появившаяся в PostgreSQL 14. Поддержка диапазонов и мультидиапазонов PostgreSQL теперь обобщена на бэкенды psycopg3, psycopg2 и asyncpg, с возможностью дальнейшей поддержки диалектов, используя объект данных Range, не зависящий от бэкенда и совместимый по конструктору с ранее используемым объектом psycopg2. Примеры использования приведены в новой документации.

    Кроме того, улучшена обработка типов диапазонов, которая автоматически выполняет приведение типов. Таким образом, при обходе на месте операторов, не предоставляющих базе данных никакого контекста, не требуется явное использование конструкции cast() для того, чтобы база данных знала нужный тип (рассматривается в разделе #8540).

    Огромное спасибо @zeeeeeb за pull request, в котором реализованы и протестированы новые типы данных и поддержка psycopg.

    References: #7156, #8540

  • [postgresql] [usecase]

    Запрос «ping», выдаваемый при конфигурировании create_engine.pool_pre_ping для psycopg, asyncpg и pg8000, но не для psycopg2, был изменен на пустой запрос (;) вместо SELECT 1; кроме того, для драйвера asyncpg было исправлено ненужное использование подготовленного оператора для этого запроса. Это сделано для того, чтобы избавить PostgreSQL от необходимости составлять план запроса при выполнении ping. В настоящее время эта операция не поддерживается драйвером psycopg2, который продолжает использовать SELECT 1.

    References: #8491

  • [postgresql] [change]

    Для работы SQLAlchemy теперь требуется PostgreSQL версии 9 или выше. Более ранние версии могут работать в некоторых ограниченных случаях.

  • [postgresql] [change] [mssql]

    Параметр UUID.as_uuid типа UUID, ранее характерный для диалекта PostgreSQL, а теперь обобщенный для Core (вместе с новым бэкенд-агностическим типом данных Uuid), теперь имеет значение по умолчанию True, что указывает на то, что объекты Python UUID по умолчанию принимаются этим типом данных. Кроме того, тип данных SQL Server UNIQUEIDENTIFIER был преобразован в тип, принимающий UUID; для устаревшего кода, использующего UNIQUEIDENTIFIER с помощью строковых значений, установите параметр UNIQUEIDENTIFIER.as_uuid в значение False.

    References: #7225

  • [postgresql] [change]

    Параметр ENUM.name для специфического для PostgreSQL типа данных ENUM теперь является обязательным аргументом в виде ключевого слова. Имя» необходимо в любом случае для того, чтобы ENUM можно было использовать, так как при отсутствии «имени» на этапе рендеринга SQL/DDL будет возникать ошибка.

  • [postgresql] [change]

    Для поддержки новых возможностей PostgreSQL, включая диалект psycopg3, а также расширенную поддержку «быстрой вставки многих», система передачи информации о типе связанных параметров в базу данных PostgreSQL была переработана для использования встроенных кастов, выдаваемых компилятором SQL, и теперь применяется для всех диалектов PostgreSQL. В отличие от предыдущего подхода, при котором для приведения к виду использовался DBAPI, который в таких случаях, как pg8000 и адаптированный драйвер asyncpg, использовал метод pep-249 setinputsizes(), а в случае драйвера psycopg2 в большинстве случаев полагался на сам драйвер, за некоторыми исключениями, сделанными для ARRAY.

    В соответствии с новым подходом, во всех диалектах PostgreSQL эти приведения выполняются по мере необходимости с использованием стиля PostgreSQL с двойной запятой в компиляторе, а использование setinputsizes() для диалектов PostgreSQL исключено, поскольку в любом случае это не было частью этих DBAPI (единственным исключением является pg8000, который добавил этот метод по просьбе разработчиков SQLAlchemy).

    К преимуществам такого подхода можно отнести производительность на каждом операторе, так как не требуется повторный проход по скомпилированному оператору во время выполнения, лучшую поддержку всех DBAPI, так как теперь существует единая последовательная система применения информации о типизации, и улучшенную прозрачность, так как вывод SQL-журнала, как и строковый вывод скомпилированного оператора, будет показывать эти приведения, присутствующие непосредственно в операторе, тогда как раньше эти приведения не были видны в выводе журнала, так как они возникали после регистрации оператора.

  • [postgresql] [bug]

    Оператор Operators.match() теперь использует plainto_tsquery() для полнотекстового поиска в PostgreSQL, а не to_tsquery(). Это сделано для того, чтобы обеспечить лучшую кросс-совместимость с поиском по другим базам данных. Полная поддержка всех полнотекстовых функций PostgreSQL остается доступной благодаря использованию func в сочетании с Operators.bool_op() (улучшенная версия Operators.op() для булевых операторов).

    References: #7086

  • [postgresql] [removed]

    Удалена поддержка нескольких устаревших драйверов:

    • pypostgresql для PostgreSQL. Он доступен в виде внешнего драйвера по адресу https://github.com/PyGreSQL.

    • pygresql для PostgreSQL.

    Пожалуйста, перейдите на один из поддерживаемых драйверов или на внешнюю версию того же драйвера.

    References: #7258

  • [postgresql] [dialect]

    Добавлена поддержка диалекта psycopg, поддерживающего как синхронное, так и асинхронное выполнение. Этот диалект доступен под именем postgresql+psycopg для функций создания движков create_engine() и create_async_engine().

    References: #6842

  • [postgresql] [psycopg2]

    Обновление диалекта psycopg2 для использования интерфейса DBAPI для выполнения двухфазных транзакций. Ранее для обработки такого рода транзакций выполнялись SQL-команды.

    References: #7238

  • [postgresql] [schema]

    Введен тип JSONPATH, который может использоваться в выражениях приведения. Это требуется в некоторых диалектах PostgreSQL при использовании таких функций, как jsonb_path_exists или jsonb_path_match, которые принимают на вход jsonpath.

    См.также

    Типы JSON - Типы PostgreSQL JSON.

    References: #8216

  • [postgresql] [reflection]

    Диалект PostgreSQL теперь поддерживает отражение индексов, основанных на выражениях. Отражение поддерживается как при использовании Inspector.get_indexes(), так и при отражении Table с помощью Table.autoload_with. Спасибо immerrr и Aidan Kane за помощь в работе над этим тикетом.

    References: #7442

mysql

  • [mysql] [usecase] [mariadb]

    Функция ROLLUP теперь будет корректно отображать WITH ROLLUP на MySql и MariaDB, что позволяет использовать group by rollup с этими бэкендами.

    References: #8503

  • [mysql] [bug]

    Исправлена проблема в MySQL Insert.on_duplicate_key_update(), которая при использовании выражения в выражении VALUES приводила к неправильному отображению имени столбца. Pull request любезно предоставлен Кристианом Сабайлой.

    This change is also backported to: 1.4.27

    References: #7281

  • [mysql] [removed]

    Удалена поддержка драйвера OurSQL для MySQL и MariaDB, так как этот драйвер, похоже, не поддерживается.

    References: #7258

mariadb

  • [mariadb] [usecase]

    Добавлена новая опция выполнения is_delete_using=True, которая потребляется ORM при использовании оператора DELETE с поддержкой ORM в сочетании со стратегией синхронизации «fetch»; эта опция указывает, что в операторе DELETE предполагается использование нескольких таблиц, что для MariaDB является синтаксисом DELETE..USING. Далее опция указывает, что RETURNING (недавно реализованный в SQLAlchemy 2.0 для MariaDB для #7011) не должен использоваться для баз данных, которые, как известно, не поддерживают синтаксис «DELETE..USING..RETURNING», даже если они поддерживают «DELETE..USING», что является текущей возможностью MariaDB.

    Смысл этой опции заключается в том, что текущая работа DELETE с поддержкой ORM не знает заранее, относится ли оператор DELETE к нескольким таблицам или нет, пока не произойдет компиляция, которая в любом случае кэшируется, но это должно быть известно, чтобы SELECT для удаляемой строки мог быть выдан заранее. Вместо того чтобы накладывать штраф за производительность на все операторы DELETE, проверяя их все на наличие этого относительно необычного SQL-шаблона, опция выполнения is_delete_using=True запрашивается с помощью нового сообщения об исключении, которое выдается на этапе компиляции. Это сообщение об исключении выдается только в следующих случаях: оператор представляет собой ORM-совместимый DELETE, в котором была запрошена стратегия синхронизации «fetch»; бэкенд - MariaDB или другой бэкенд с этим специфическим ограничением; в процессе начальной компиляции было обнаружено, что в противном случае оператор выдаст «DELETE..USING..RETURNING». Применяя опцию выполнения, ORM понимает, что вместо этого нужно выполнить SELECT. Аналогичная опция реализована и для UPDATE с поддержкой ORM, но в настоящее время нет бэкенда, где она была бы необходима.

    References: #8344

  • [mariadb] [usecase]

    Добавлена поддержка INSERT..RETURNING и DELETE..RETURNING для диалекта MariaDB. UPDATE..RETURNING пока не поддерживается MariaDB. MariaDB поддерживает INSERT..RETURNING начиная с версии 10.5.0 и DELETE..RETURNING начиная с версии 10.0.5.

    References: #7011

sqlite

  • [sqlite] [usecase]

    Добавлен новый параметр в SQLite для методов отражения sqlite_include_internal=True; при его отсутствии локальные таблицы, начинающиеся с префикса sqlite_, которые в документации SQLite отмечены как таблицы «внутренней схемы», например, таблица sqlite_sequence, созданная для поддержки столбцов «AUTOINCREMENT», не будут включаться в методы отражения, возвращающие списки локальных объектов. Это позволяет избежать проблем, например, при использовании автогенерации Alembic, которая ранее считала такие таблицы, сгенерированные SQLite, удаленными из модели.

    References: #8234

  • [sqlite] [usecase]

    Добавлена поддержка RETURNING для диалекта SQLite. SQLite поддерживает RETURNING начиная с версии 3.35.

    References: #6195

  • [sqlite] [usecase]

    Диалект SQLite теперь поддерживает синтаксис UPDATE..FROM, позволяющий операторам UPDATE ссылаться на дополнительные таблицы в рамках критерия WHERE без использования подзапросов. Этот синтаксис автоматически вызывается при использовании конструкции Update, когда используется более одной таблицы или другой сущности или selectable.

    References: #7185

  • [sqlite] [performance] [usecase]

    Теперь для разбора входящих значений строк времени, даты и времени в SQLite используются методы стандартной библиотеки Python lib fromisoformat(). Это повышает производительность по сравнению с предыдущим подходом, основанным на регулярных выражениях, а также автоматически учитывает форматы времени и даты, содержащие либо шестизначный формат «микросекунды», либо трехзначный формат «миллисекунды».

    References: #7029

  • [sqlite] [bug]

    Убрано предупреждение, выдаваемое типом Numeric, о том, что DBAPI не поддерживают нативно десятичные значения. Это предупреждение было ориентировано на SQLite, который не имеет реального способа без дополнительных расширений или обходных путей работать с числовыми значениями точности более 15 значащих цифр, поскольку использует для представления чисел только математику с плавающей точкой. Поскольку это известное и документированное ограничение в самом SQLite, а не причуда драйвера pysqlite, нет необходимости предупреждать SQLAlchemy об этом. В остальном данное изменение не изменяет работу с точными числами. Значения могут по-прежнему обрабатываться как Decimal() или float(), как это настроено в типах данных Numeric, Float и других, только без возможности поддерживать точность более 15 значащих цифр при использовании SQLite, если не используются альтернативные представления, например, строки.

    References: #7299

  • [sqlite] [bug] [performance]

    Диалект SQLite теперь по умолчанию принимает значение QueuePool при использовании базы данных на основе файлов. Это устанавливается вместе с установкой параметра check_same_thread в значение False. Было замечено, что предыдущий подход, при котором по умолчанию устанавливалось значение NullPool, не удерживающее соединения с базой данных после их освобождения, действительно оказывал ощутимое негативное влияние на производительность. Как обычно, класс пула настраивается с помощью параметра create_engine.poolclass.

    References: #7490

mssql

  • [mssql] [usecase]

    Реализовано отражение флага «кластеризованный индекс» mssql_clustered для диалекта SQL Server. Pull request любезно предоставлен Джоном Ленноксом.

    References: #8288

  • [mssql] [usecase]

    Добавлена поддержка комментариев таблиц и столбцов на MSSQL при создании таблицы. Добавлена поддержка отражения комментариев к таблицам. Спасибо Daniel Hall за помощь в этом pull request.

    References: #7844

  • [mssql] [bug]

    Параметр use_setinputsizes для диалекта mssql+pyodbc теперь имеет значение по умолчанию True; это сделано для того, чтобы неюникодные сравнения строк привязывались pyodbc к pyodbc.SQL_VARCHAR, а не pyodbc.SQL_WVARCHAR, что позволяет использовать индексы к столбцам VARCHAR. Для того чтобы параметр fast_executemany=True продолжал работать, режим use_setinputsizes теперь пропускает вызов cursor.setinputsizes() именно тогда, когда fast_executemany имеет значение True, а конкретный используемый метод - cursor.executemany(), который не поддерживает setinputsizes. Изменение также добавляет соответствующую типизацию pyodbc DBAPI для значений, типизированных как Unicode или UnicodeText, а также изменяет базовый тип данных JSON для рассмотрения строковых значений JSON как Unicode, а не String.

    References: #8177

  • [mssql] [removed]

    Удалена поддержка драйвера mxodbc из-за отсутствия тестирования. Пользователи ODBC могут использовать диалект pyodbc, который полностью поддерживается.

    References: #7258

oracle

  • [oracle] [feature]

    Добавить поддержку нового драйвера oracle oracledb.

    References: #8054

  • [oracle] [feature]

    Реализована поддержка DDL и рефлексии для типов данных FLOAT, включающих явное значение «binary_precision». При использовании специфического для Oracle типа данных FLOAT можно указать новый параметр FLOAT.binary_precision, который будет напрямую отображать точность Oracle для типов с плавающей точкой. Это значение интерпретируется при отражении. При отражении типа данных FLOAT возвращаемый тип данных будет одним из следующих: DOUBLE_PRECISION для FLOAT с точностью 126 (это также точность Oracle по умолчанию для FLOAT), REAL для точности 63 и FLOAT для пользовательской точности, согласно документации Oracle.

    В рамках этого изменения общее значение Float.precision явно отвергается при генерации DDL для Oracle, поскольку такая точность не может быть точно преобразована в «двоичную точность»; вместо этого в сообщении об ошибке предлагается использовать TypeEngine.with_variant(), чтобы можно было точно выбрать специфическую форму точности Oracle. Это изменение поведения является обратно несовместимым, так как предыдущее значение «precision» молча игнорировалось для Oracle.

    References: #5465

  • [oracle] [feature]

    Для диалекта cx_Oracle реализована полная поддержка «RETURNING», охватывающая два отдельных вида функциональности:

    • Реализовано многорядное ВОЗВРАЩЕНИЕ, т.е. теперь для операторов DML, создающих более одной строки для ВОЗВРАЩЕНИЯ, будет получено несколько строк ВОЗВРАЩЕНИЯ.

    • Реализована также функция «executemany RETURNING», позволяющая при использовании cursor.executemany() выдать строку за строку. Реализация этой части функции позволяет значительно повысить производительность ORM-вставок, подобно тому, как это было сделано для psycopg2 в изменении SQLAlchemy 1.4 ORM Пакетные вставки с psycopg2 теперь в большинстве случаев выполняют пакетные операции с RETURNING.

    References: #6245

  • [oracle] [usecase]

    Теперь Oracle по умолчанию использует синтаксис FETCH FIRST N ROWS / OFFSET для поддержки ограничений/смещений в Oracle 12c и выше. Этот синтаксис уже был доступен при прямом использовании Select.fetch(), теперь он подразумевается и для Select.limit() и Select.offset().

    References: #8221

  • [oracle] [change]

    Материализованные представления в oracle теперь отражаются как представления. В предыдущих версиях SQLAlchemy представления возвращались среди имен таблиц, а не среди имен представлений. В качестве побочного эффекта этого изменения они не отражаются по умолчанию методом MetaData.reflect(), если не задан параметр views=True. Чтобы получить список материализованных представлений, используйте новый метод проверки Inspector.get_materialized_view_names().

  • [oracle] [bug]

    В диалектах cx_Oracle и oracledb внесены коррективы в типы данных BLOB / CLOB / NCLOB с целью повышения производительности на основе рекомендаций разработчиков Oracle.

    References: #7494

  • [oracle] [bug]

    В связи с устареванием create_engine.implicit_returning, функция «implicit_returning» теперь включена для диалекта Oracle во всех случаях; ранее эта функция отключалась при обнаружении версии Oracle 8/8i, однако в онлайн-документации указано, что обе версии поддерживают тот же синтаксис RETURNING, что и современные версии.

    References: #6962

  • [oracle]

    cx_Oracle 7 теперь является минимальной версией для cx_Oracle.

misc

  • [removed] [sybase]

    Удален внутренний диалект «sybase», который был устаревшим в предыдущих версиях SQLAlchemy. Поддержка сторонних диалектов доступна.

    References: #7258

  • [removed] [firebird]

    Удален внутренний диалект «firebird», который был устаревшим в предыдущих версиях SQLAlchemy. Поддержка сторонних диалектов доступна.

    References: #7258

Вернуться на верх