1.4 Changelog¶
В этом документе подробно описаны отдельные изменения на уровне проблем, внесенные в релизы 1.4. Для получения подробного обзора того, что нового появилось в 1.4, см. раздел Что нового в SQLAlchemy 1.4?.
1.4.49¶
no release date1.4.48¶
Released: April 30, 2023orm¶
Исправлена критическая проблема кэширования, когда сочетание композиций выражений
aliased()
иhybrid_property()
приводило к несовпадению ключей кэша, в результате чего ключи кэша удерживали реальный объектaliased()
и не совпадали с ключами эквивалентных конструкций, заполняя кэш.References: #9728
Исправлена ошибка, при которой различные ORM-специфичные геттеры, такие как
ORMExecuteState.is_column_load
,ORMExecuteState.is_relationship_load
,ORMExecuteState.loader_strategy_path
и т.д., выдавали ошибкуAttributeError
, если сам SQL-оператор представлял собой «составной select», например, UNION.References: #9634
Исправлен бесконечный цикл, который мог возникать при использовании функции «отношение к псевдоклассу», а также при указании в загрузчике рекурсивного ускоренного загрузчика, например
lazy="selectinload"
, в сочетании с другим ускоренным загрузчиком на противоположной стороне. Исправлена проверка на наличие циклов для включения отношений с псевдоклассами.References: #9590
1.4.47¶
Released: March 18, 2023sql¶
Исправлена ошибка/регрессия, при которой использование
bindparam()
с тем же именем, что и столбец, в методеUpdate.values()
вUpdate
, а также в методеInsert.values()
вInsert
только в версии 2.0 в некоторых случаях приводило к тому, что SQL-выражение, в котором был представлен параметр, не выполнялось, заменяясь новым параметром с тем же именем и отбрасывая все остальные элементы SQL-выражения, такие как SQL-функции и т.д. В данном случае речь идет об операторах, построенных на основе сущностей ORM, а не простых экземпляровTable
, но это может произойти и в том случае, если оператор был вызван с помощьюSession
илиConnection
.Update
часть проблемы присутствовала как в 2.0, так и в 1.4 и перенесена в 1.4.References: #9075
Исправлена ошибка stringify для DDL-конструкций
CreateSchema
иDropSchema
, которая при строке без диалекта приводила к ошибкеAttributeError
.References: #7664
Исправлена критическая проблема кэширования SQL, когда при использовании функции пользовательского оператора
Operators.op()
не создавался соответствующий ключ кэша, что приводило к снижению эффективности работы кэша SQL.References: #9506
mypy¶
В плагин mypy внесены коррективы, учитывающие некоторые потенциальные изменения, которые могут быть внесены в проблему #236 sqlalchemy2-stubs при использовании SQLAlchemy 1.4. Эти изменения синхронизируются с SQLAlchemy 2.0. Изменения также обратно совместимы со старыми версиями sqlalchemy2-stubs.
Исправлен сбой в плагине mypy, который мог произойти как в версии 1.4, так и в версии 2.0, если использовался декоратор для декоратора
mapped()
, на который ссылалось выражение, содержащее более двух компонентов (например,@Backend.mapper_registry.mapped
). Теперь этот сценарий игнорируется; при использовании плагина выражение декоратора должно быть двухкомпонентным (т.е.@reg.mapped
).References: #9102
postgresql¶
В диалект asyncpg добавлена поддержка возврата значения
cursor.rowcount
для операторов SELECT, если оно доступно. Хотя это не является типичным использованиемcursor.rowcount
, другие диалекты PostgreSQL обычно предоставляют это значение. Pull request любезно предоставлен Майклом Горвеном.References: #9048
mysql¶
Добавлена поддержка отражения индексов MySQL для корректного отражения словаря
mysql_length
, который ранее игнорировался.References: #9047
mssql¶
Исправлена ошибка, при которой имя схемы, заданное со скобками, но без точек внутри имени, для таких параметров, как
Table.schema
, не интерпретировалось в контексте документированного поведения диалекта SQL Server по интерпретации явных скобок как разделителей токенов, впервые добавленного в 1.2 для #2626, при обращении к имени схемы в операциях отражения. Первоначальное предположение для поведения #2626 состояло в том, что специальная интерпретация скобок была значима только при наличии точек, однако на практике скобки не включаются как часть имени идентификатора во всех операциях рендеринга SQL, поскольку они не являются допустимыми символами в обычных или разграниченных идентификаторах. Pull request courtesy Shan.References: #9133
oracle¶
1.4.46¶
Released: January 3, 2023general¶
Новое предупреждение об устаревании «uber warning» теперь выдается во время выполнения программы в первый раз, когда обычно выдается любое предупреждение об устаревании SQLAlchemy 2.0, но не установлена переменная окружения
SQLALCHEMY_WARN_20
. Предупреждение выдается не более одного раза, после чего устанавливается логическое значение, предотвращающее его повторное появление.Данное предупреждение об устаревании призвано уведомить пользователей, которые, возможно, не установили в файлах требований соответствующее ограничение для защиты от неожиданного обновления SQLAlchemy 2.0, а также предупредить о том, что процесс обновления SQLAlchemy 2.0 доступен, поскольку первый полноценный релиз 2.0 ожидается очень скоро. Предупреждение об устаревании может быть отключено установкой переменной окружения
SQLALCHEMY_SILENCE_UBER_WARNING
в значение"1"
.References: #8983
Исправлена регрессия, при которой базовый модуль compat обращался к
platform.architecture()
для определения некоторых свойств системы, что приводило к слишком широкому вызову системы по сравнению с вызовом системного уровняfile
, недоступному при некоторых обстоятельствах, в том числе в некоторых конфигурациях безопасного окружения.References: #8995
orm¶
engine¶
Исправлено давнее состояние гонки в пуле соединений, которое могло возникать при использовании схем eventlet/gevent monkeypatching в сочетании с условиями eventlet/gevent
Timeout
, когда проверка пула соединений, прерванная из-за таймаута, не успевала очистить состояние отказа, что приводило к «утечке» базовой записи соединения, а иногда и самого соединения с базой данных, оставляя пул в неработоспособном состоянии с недоступными записями. Впервые эта проблема была выявлена и исправлена в SQLAlchemy 1.2 для #4225, однако режимы отказа, обнаруженные в этом исправлении, не учитывалиBaseException
, а неException
, что не позволяло перехватить эвентлет/гевентTimeout
. Кроме того, был выявлен и исправлен блок внутри начального соединения с пулом, в котором появился блокBaseException
-> «clean failed connect», учитывающий то же самое условие в этом месте. Большое спасибо пользователю Github @niklaus за упорную работу по выявлению и описанию этой сложной проблемы.References: #8974
sql¶
Добавлен параметр
FunctionElement.column_valued.joins_implicitly
, который позволяет предотвратить появление предупреждения о «картезианском произведении» при использовании таблично-значных или столбцово-значных функций. Этот параметр уже был введен дляFunctionElement.table_valued()
в #7845, однако его не удалось добавить и дляFunctionElement.column_valued()
.References: #9009
Исправлена ошибка, когда при использовании выражения, тип которого включал
TypeEngine.bind_expression()
, в контексте «расширяющего» (т.е. «IN») параметра в сочетании с параметром компилятораliteral_binds
, компиляция SQL заканчивалась неудачей (assertion fail в 2.0, NoneType error в 1.4).References: #8989
Исправлена проблема в лямбда-функции SQL, когда вычисляемый тип литерального значения не учитывал правила коэрцитивности типа «сравнивается с типом», что приводило к отсутствию информации о типе для SQL-выражений, таких как сравнение с элементами
JSON
и подобных.References: #9029
postgresql¶
Добавлен тип PostgreSQL
MACADDR8
. Pull request любезно предоставлен Asim Farooq.References: #8393
Исправлена ошибка, при которой параметр PostgreSQL
Insert.on_conflict_do_update.constraint
принимал объектIndex
, но не разворачивал этот индекс в отдельные индексные выражения, а вместо этого выводил его имя в предложение ON CONFLICT ON CONSTRAINT, которое не принимается PostgreSQL; форма «constraint name» принимает только уникальные или исключающие имена ограничений. Параметр продолжает принимать индекс, но теперь разлагает его на составные выражения для рендеринга.References: #9023
sqlite¶
Исправлена регрессия, вызванная добавленной в 1.4.45 поддержкой отражения частичных индексов на SQLite для #8804, когда команда прагмы
index_list
в очень старых версиях SQLite (возможно, до 3.8.9) не возвращала текущее ожидаемое количество столбцов, что приводило к исключениям, возникающим при отражении таблиц и индексов.References: #8969
tests¶
Исправлена проблема в файле tox.ini, когда изменения в серии tox 4.0 в формате «passenv» приводили к некорректной работе tox, в частности, вызывая ошибку начиная с tox 4.0.6.
Добавлено новое правило исключения для сторонних диалектов
unusual_column_name_characters
, которое может быть «закрыто» для сторонних диалектов, не поддерживающих имена колонок с необычными символами, такими как точки, косые черты или знаки процента, даже если имя правильно заключено в кавычки.References: #9002
1.4.45¶
Released: December 10, 2022orm¶
Исправлена ошибка, при которой
Session.merge()
не сохранял текущее загруженное содержимое атрибутов отношений, указанных параметромrelationship.viewonly
, что приводило к нарушению стратегий, использующихSession.merge()
для извлечения полностью загруженных объектов из кэша и других подобных приемов. В связанном с этим изменении исправлена проблема, когда объект, содержащий загруженное отношение, которое, тем не менее, было настроено какlazy='raise'
на отображении, терпел неудачу при передаче вSession.merge()
; теперь проверка на «повышение» приостанавливается в процессе слияния, предполагая, что параметрSession.merge.load
остается по умолчаниюTrue
.В целом это поведенческая корректировка изменения, введенного в серии 1.4 начиная с версии #4994, которое убрало «слияние» из набора каскадов, применяемых по умолчанию к отношениям «только для просмотра». Поскольку отношения «viewonly» не сохраняются ни при каких обстоятельствах, разрешение передачи их содержимого при «merge» не влияет на поведение сохранения целевого объекта. Это позволяет
Session.merge()
корректно использовать один из вариантов его применения - добавление вSession
объектов, которые были загружены в другом месте, часто для восстановления из кэша.References: #8862
Исправлены проблемы в
with_expression()
, когда выражения, состоящие из столбцов, на которые есть ссылки из вложенного SELECT, в некоторых контекстах не выводили корректный SQL, в случае если выражение имело имя метки, совпадающее с атрибутом, который использовалquery_expression()
, даже еслиquery_expression()
не имел выражения по умолчанию. На данный момент, если выражениеquery_expression()
все же имеет выражение по умолчанию, то это имя метки все равно используется по умолчанию, а дополнительная метка с тем же именем будет по-прежнему игнорироваться. В целом, данный случай является довольно сложным, поэтому, возможно, потребуются дополнительные корректировки.References: #8881
engine¶
Исправлена проблема, при которой метод
Result.freeze()
не работал для текстового SQL, использующегоtext()
илиConnection.exec_driver_sql()
.References: #8963
sql¶
Теперь в случае неудачи любой операции рендеринга «literal bindparam» выбрасывается информативное сообщение re-raise с указанием самого значения и используемого типа данных, чтобы помочь в отладке при рендеринге буквальных параметров в операторе.
References: #8800
Исправлен ряд проблем, связанных с расположением, а иногда и идентичностью отображаемых связанных параметров, например, для SQLite, asyncpg, MySQL, Oracle и других. В некоторых скомпилированных формах порядок параметров сохранялся некорректно, например, в функции PostgreSQL
regexp_replace()
, во «вложенной» конструкцииCTE
, впервые появившейся в #4123, а также в таблицах с выбором, сформированных методомFunctionElement.column_valued()
в Oracle.References: #8827
asyncio¶
Из
AsyncResult
удален нефункциональный методmerge()
. Этот метод никогда не работал и был включен вAsyncResult
по ошибке.References: #8952
postgresql¶
Внесена поправка в то, как диалект PostgreSQL учитывает типы столбцов при отражении столбцов из таблицы, для учета альтернативных бэкендов, которые могут возвращать NULL из функции PG
format_type()
.References: #8748
sqlite¶
Добавлена поддержка бэкенда SQLite для отражения ключевых слов «DEFERRABLE» и «INITIALLY», которые могут присутствовать в конструкции внешнего ключа. Pull request любезно предоставлен Майклом Горвеном.
References: #8903
Добавлена поддержка отражения ориентированных на выражения критериев WHERE, включенных в индексы на диалекте SQLite, аналогично тому, как это делается на диалекте PostgreSQL. Pull request любезно предоставлен Тобиасом Пфайффером.
References: #8804
Резервное копирование исправления отражения SQLite уникальных ограничений в присоединенных схемах, выпущенного в 2.0 в виде небольшой части #4379. Ранее уникальные ограничения в присоединенных схемах игнорировались отражением SQLite. Pull request любезно предоставлен Майклом Горвеном.
References: #8866
oracle¶
Продолжение исправления ошибки Oracle #8708, выпущенной в версии 1.4.43, в которой имена связанных параметров, начинающиеся с символов подчеркивания, запрещенных Oracle, все еще не приводились в надлежащий вид при любых обстоятельствах.
References: #8708
Исправлена проблема в компиляторе Oracle, когда синтаксис для
FunctionElement.column_valued()
был неверен, что приводило к появлению имениCOLUMN_VALUE
без корректной квалификации исходной таблицы.References: #8945
1.4.44¶
Released: November 12, 2022sql¶
Исправлена критическая проблема с памятью при генерации ключей кэша, когда для очень больших и сложных ORM-выражений, использующих множество ORM-псевдонимов с подзапросами, генерация ключей кэша могла приводить к созданию слишком больших ключей, на порядки превышающих размер самого выражения. Большое спасибо Rollo Konig Brock за их очень терпеливую и длительную помощь в выявлении этой проблемы.
References: #8790
postgresql¶
Только для диалектов PostgreSQL и SQL Server компилятор настроен таким образом, что при выводе выражений столбцов в предложении RETURNING для элементов SQL-выражений, генерирующих метку, предлагается использовать метку «non anon», которая используется в операторах SELECT; основным примером является SQL-функция, которая может выдаваться как часть типа столбца, где имя метки по умолчанию должно совпадать с именем столбца. Это восстанавливает не вполне определенное поведение, которое изменилось в версии 1.4.21 из-за #6718, #6710. Диалект Oracle имеет другую реализацию RETURNING и не был затронут этой проблемой. В версии 2.0 внесены общие изменения для широкого расширения поддержки RETURNING в других бэкендах.
References: #8770
oracle¶
Исправлена проблема в диалекте Oracle, когда оператор INSERT, использующий
insert(some_table).values(...).returning(some_table)
сразу против всего объектаTable
, не выполнялся, вызывая исключение.
tests¶
Исправлена проблема, при которой параметр
--disable-asyncio
в тестовом наборе не запускал тесты greenlet, а также не предотвращал использование «оберточного» greenlet для всего набора. Теперь этот параметр гарантирует, что в течение всего прогона не будет использоваться greenlet или asyncio.References: #8793
В тестовый набор, тестирующий плагин Mypy, внесены изменения в версии Mypy 0.990, касающиеся обработки вывода сообщений, которые влияют на интерпретацию sys.path при определении необходимости вывода заметок и ошибок для определенных файлов. Это изменение нарушило работу тестового набора, так как файлы в самой тестовой директории больше не выдавали сообщений при запуске под управлением API mypy.
1.4.43¶
Released: November 4, 2022orm¶
Исправлена проблема в объединенной ускоренной загрузке, когда при определенной комбинации внешней/внутренней объединенной ускоренной загрузки происходил сбой утверждения при ускоренной загрузке трех мэпперов, где средний мэппер был унаследованным мэппером подкласса.
References: #8738
Исправлена ошибка, связанная с конструкциями
Select
, когда комбинацииSelect.select_from()
сSelect.join()
, а также при использованииSelect.join_from()
приводили к тому, что функцияwith_loader_criteria()
, а также критерии IN, необходимые для запросов наследования одной таблицы, не отображались в тех случаях, когда в предложении columns запроса не была явно указана левая сторона сущности JOIN. Теперь правильная сущность передается в объектJoin
, который генерируется внутренне, что позволяет корректно добавлять критерии к левосторонней сущности.References: #8721
При использовании опции
with_loader_criteria()
в качестве опции загрузчика, добавленной к определенному «пути загрузчика», например, при использовании ее внутриLoad.options()
, теперь выдается информативное исключение. Такое использование не поддерживается, посколькуwith_loader_criteria()
предназначена только для использования в качестве опции загрузчика верхнего уровня. Ранее возникала внутренняя ошибка.References: #8711
Улучшен «режим словаря» для
Session.get()
, благодаря чему имена синонимов, ссылающиеся на имена атрибутов первичного ключа, могут быть указаны в именованном словаре.References: #8753
Исправлена проблема, при которой загрузка «selectin_polymorphic» для отображателей наследования работала некорректно, если параметр
Mapper.polymorphic_on
ссылался на SQL-выражение, которое не было непосредственно отображено на класс.References: #8704
Исправлена проблема, когда при использовании объекта
Query
в качестве итератора базовый курсор DBAPI не закрывался, если в процессе итерации возникало определенное пользователем исключение, что приводило к закрытию итератора интерпретатором Python. При использованииQuery.yield_per()
для создания курсоров на стороне сервера это приводило к обычным для MySQL проблемам, связанным с рассинхронизацией курсоров на стороне сервера, и без прямого доступа к объектуResult
код конечного пользователя не мог получить доступ к курсору, чтобы закрыть его.Для решения проблемы внутри метода итератора применяется catch для
GeneratorExit
, который закроет объект result в тех случаях, когда итератор был прерван, и по определению будет закрыт интерпретатором Python.В рамках этого изменения, реализованного в серии 1.4, было обеспечено наличие методов
.close()
во всех реализацияхResult
, включаяScalarResult
,MappingResult
. В версии 2.0 это изменение также включает новые паттерны менеджера контекста для использования с классамиResult
.References: #8710
engine¶
Исправлена проблема, при которой крючок события
PoolEvents.reset()
вызывался не во всех случаях, когдаConnection
был закрыт и находился в процессе возврата своего DBAPI-соединения в пул соединений.Сценарий заключался в том, что хук
Connection
уже выполнил.rollback()
на своем DBAPI-соединении в процессе возврата соединения в пул, где он инструктировал пул соединений не выполнять свой собственный «сброс», чтобы сэкономить на дополнительном вызове метода. Однако это не позволяло использовать пользовательские схемы сброса пула в рамках данного хука, поскольку такие хуки по определению выполняют нечто большее, чем просто вызов.rollback()
, и должны вызываться при любых обстоятельствах. Это была регрессия, появившаяся в версии 1.4.В версии 1.4 функция
PoolEvents.checkin()
остается актуальной в качестве альтернативного крючка событий для использования в пользовательских реализациях «сброса». В версии 2.0 появится улучшенная версияPoolEvents.reset()
, которая будет вызываться для дополнительных сценариев, таких как завершение asyncio-соединений, а также ей будет передаваться контекстная информация о сбросе, что позволит реализовать схемы «пользовательского сброса соединений», которые могут по-разному реагировать на различные сценарии сброса.References: #8717
Обеспечено включение во все объекты
Result
методаResult.close()
, а также атрибутаResult.closed
, в том числе вScalarResult
иMappingResult
.References: #8710
sql¶
Исправлена проблема, из-за которой конструкция
literal_column()
не могла корректно работать в контексте конструкцииSelect
, а также в других потенциальных местах генерации «анонимных меток», если литеральное выражение содержало символы, которые могли помешать строкам форматирования, например, открытую круглую скобку, что связано с особенностями реализации структуры «анонимная метка».References: #8724
mssql¶
Исправлена проблема с
Inspector.has_table()
, которая при использовании к временной таблице диалекта SQL Server приводила к ошибке на некоторых вариантах Azure из-за лишнего запроса информационной схемы, который не поддерживается на этих версиях сервера. Pull request любезно предоставлен Майком Барри.References: #8714
Исправлена проблема с
Inspector.has_table()
, которая при использовании против представления с диалектом SQL Server ошибочно возвращалаFalse
, что связано с регрессией в серии 1.4, удалившей поддержку этой функции на SQL Server. В серии 2.0, использующей другую архитектуру отражения, эта проблема отсутствует. Добавлена тестовая поддержка, чтобы убедиться, чтоhas_table()
продолжает работать в соответствии со спецификацией, касающейся представлений.References: #8700
oracle¶
Исправлена проблема, при которой имена связанных параметров, в том числе автоматически получаемые из аналогичных по названию столбцов базы данных, содержащие символы, которые обычно требуют кавычек в Oracle, не экранировались при использовании «расширяющих параметров» в диалекте Oracle, что приводило к ошибкам выполнения. Обычное «кавычки» для связанных параметров, используемые диалектом Oracle, в архитектуре «расширяющих параметров» не применяются, поэтому вместо них используется экранирование для большого диапазона символов, теперь с использованием списка символов/эскейпов, специфичных для Oracle.
References: #8708
Исправлена проблема, при которой представление
nls_session_parameters
, запрашиваемое при первом подключении для получения десятичного символа по умолчанию, могло быть недоступно в зависимости от режимов подключения Oracle, что приводило к возникновению ошибки. Подход к определению десятичного символа был упрощен и теперь проверяется непосредственно десятичное значение, а не чтение системных представлений, что работает на любом бэкенде/драйвере.References: #8744
1.4.42¶
Released: October 16, 2022orm¶
Словарь
Session.execute.bind_arguments
больше не мутирует при передаче вSession.execute()
и подобные методы; вместо этого он копируется во внутренний словарь при изменении состояния. Кроме всего прочего, это устраняет проблему, когда «clause», передаваемый методуSession.get_bind()
, некорректно ссылался на конструкциюSelect
, используемую для стратегии синхронизации «fetch», в то время как реальный запрос былDelete
илиUpdate
. Это мешало бы рецептам «сессий маршрутизации».References: #8614
В конфигурациях ORM выдается предупреждение, когда явная аннотация
remote()
применяется к столбцам, локальным для непосредственного сопоставленного класса, в то время как ссылающийся класс не содержит ни одного из тех же столбцов таблицы. В идеале это должно приводить к ошибке, поскольку с точки зрения отображения это некорректно.References: #7094
Предупреждение выдается при попытке сконфигурировать сопоставленный класс в иерархии наследования, где сопоставителю не задана полиморфная идентичность, но назначен полиморфный столбец-дискриминатор. Такие классы должны быть абстрактными, если их никогда не предполагается загружать напрямую.
References: #7545
В версии 1.4 исправлена ошибка в
contains_eager()
, когда логика «обертывания в подзапрос» вjoinedload()
могла случайно срабатывать при использовании функцииcontains_eager()
с аналогичными операторами (например, использующимиdistinct()
,limit()
илиoffset()
), что приводило к вторичным проблемам с запросами, использующими некоторые комбинации имен SQL-меток и алиасинга. Такая «обертка» не подходит дляcontains_eager()
, где всегда действовал контракт, согласно которому пользовательский SQL-оператор не модифицируется, за исключением добавления соответствующих колонок для извлечения.References: #8569
Исправлена регрессия, при которой использование ORM update() с synchronize_session=“fetch“ приводило к ошибке из-за использования оценщиков, которые теперь используются для определения in-Python-значения для выражений в предложении SET при обновлении объектов; если в оценщиках используются математические операторы для нечисловых значений, таких как PostgreSQL JSONB, то условие неоцененности не определялось корректно. Теперь оценщик ограничивает использование математических операторов мутации только числовыми типами, за исключением «+», который продолжает работать и для строк. В SQLAlchemy 2.0 это ограничение может быть изменено в сторону полного извлечения значений SET вместо использования оценки.
References: #8507
engine¶
Исправлена проблема, когда смешивание «*» с дополнительными явно именованными выражениями столбцов в предложении columns конструкции
select()
приводило к тому, что нацеливание на столбец результата иногда рассматривало имя метки или другие неповторяющиеся имена как неоднозначную цель.References: #8536
asyncio¶
Улучшена реализация
asyncio.shield()
, используемая в менеджерах контекста, как добавлено в #8145, таким образом, что операция «закрыть» заключена вasyncio.Task
, на которую по мере выполнения операции делаются сильные ссылки. Это сделано в соответствии с документацией Python, указывающей, что в противном случае задача не имеет сильной ссылки.References: #8516
postgresql¶
aggregate_order_by
теперь поддерживает генерацию кэша.References: #8574
mysql¶
Регулярное выражение, используемое для соответствия запросу «CREATE VIEW» при тестировании представлений, стало работать более гибко, больше не требуя специального ключевого слова «ALGORITHM» в середине, которое должно было быть необязательным, но работало некорректно. Это изменение позволяет отражению представлений более полно работать на MySQL-совместимых вариантах, таких как StarRocks. Pull request любезно предоставлен Джоном Бодли.
References: #8588
mssql¶
Исправлена очередная регрессия в выборке уровня изоляции SQL Server (см. #8231, #8475), на этот раз с «Microsoft Dynamics CRM Database via Azure Active Directory», в которой, очевидно, полностью отсутствует представление
system_views
. Отлов ошибок был расширен таким образом, что при наличии подключения к базе данных этот метод ни при каких обстоятельствах не даст сбоя.References: #8525
1.4.41¶
Released: September 6, 2022orm¶
Исправлена проблема с прослушиванием событий, при которой слушатели событий, добавленные в суперкласс, терялись, если создавался подкласс, в котором затем появлялись свои собственные слушатели. Практический пример - класс
sessionmaker
, созданный после того, как события были связаны с классомSession
.References: #8467
Ужесточена стратегия кэш-ключей для конструкций
aliased()
иwith_polymorphic()
. Хотя проблемы, связанные с кэшированием реальных высказываний, легко продемонстрировать (если вообще возможно), эти две конструкции не включали в свои кэш-ключи достаточно того, что делает их уникальными, чтобы кэширование только по псевдослучайной конструкции было точным.References: #8401
В версии 1.4 исправлена ошибка, из-за которой запрос с объединенным наследованием, помещенный в качестве подзапроса во вложенный запрос к той же сущности, не отображал корректно JOIN для внутреннего запроса. Эта проблема проявлялась двумя различными способами до и после версии 1.4.18 (связанная проблема #6595), в одном случае JOIN отображался дважды, в другом - полностью терял JOIN. Для решения проблемы условия, при которых применяется «полиморфная загрузка», были изменены таким образом, чтобы не вызывать ее для простых запросов с объединенным наследованием.
References: #8456
Исправлена проблема в расширении
sqlalchemy.ext.mutable
, когда ссылки коллекции на родительский объект терялись, если объект объединялся сSession.merge()
при одновременной передачеSession.merge.load
в качестве False.References: #8446
Исправлена проблема с
with_loader_criteria()
, когда переменная закрытия, используемая в качестве значения связанного параметра в лямбде, не переносилась корректно в дополнительные загрузчики отношений, такие какselectinload()
иlazyload()
, после кэширования оператора, а вместо нее использовалось устаревшее первоначально кэшированное значение.References: #8399
sql¶
Исправлена проблема, когда при использовании конструкции
table()
, передающей строку в качестве параметраtable.schema
, при формировании ключа кэша не учитывалась строка «schema», что приводило к коллизиям кэширования при использовании нескольких одноименных конструкцийtable()
с разными схемами.References: #8441
asyncio¶
Интегрирована поддержка вызова метода asyncpg
terminate()
для случаев, когда пул соединений перерабатывает соединение, возможно, завершившееся по таймауту, когда происходит сборка мусора, который не был изящно закрыт, а также когда соединение было признано недействительным. Это позволяет asyncpg завершить соединение, не дожидаясь ответа, который может иметь длительный таймаут.References: #8419
mssql¶
Исправлена регрессия, вызванная исправлением #8231, выпущенным в версии 1.4.40, когда при попытке определить текущий уровень изоляции транзакции соединение не выполнялось, если у пользователя не было прав на запрос системных представлений
dm_exec_sessions
илиdm_pdw_nodes_exec_sessions
.References: #8475
1.4.40¶
Released: August 8, 2022orm¶
Исправлена проблема, при которой многократное обращение к CTE в сочетании с полиморфным SELECT могло привести к созданию нескольких «клонов» одного и того же CTE, в результате чего эти два CTE рассматривались как дубликаты. Для решения этой проблемы оба CTE при возникновении такой ситуации подвергаются глубокому сравнению, чтобы убедиться в их эквивалентности, после чего они рассматриваются как эквивалентные.
References: #8357
Конструкция
select()
, переданная в качестве единственного аргумента „*“ дляSELECT *
, либо через строку, либо черезtext()
, либо черезliteral_column()
, будет интерпретироваться как SQL-оператор уровня Core, а не как оператор уровня ORM. Это необходимо для того, чтобы при расширении*
на любое количество столбцов в результате были возвращены все столбцы. Для интерпретацииselect()
на уровне ORM необходимо заранее знать имена и типы всех столбцов ORM, чего нельзя добиться при использовании'*'
.Если среди других выражений одновременно с оператором ORM используется
'*
, то возникает ошибка, так как это не может быть правильно интерпретировано ORM.References: #8235
orm declarative¶
Исправлена проблема, при которой в иерархии классов, организованной как абстрактные или декларативные классы mixin, нельзя было объявить отдельные колонки в суперклассе, которые затем корректно копировались в вызываемую переменную
declared_attr
, желающую использовать их в классе-потомке.References: #8190
engine¶
В Core реализована новая опция
Connection.execution_options.yield_per
для выполненияConnection
, которая повторяет аналогичную опцию yield_per, доступную в ORM. Опция устанавливает обе опцииConnection.execution_options.stream_results
одновременно с вызовомResult.yield_per()
, чтобы обеспечить наиболее распространенную конфигурацию потокового результата, которая также повторяет по шаблону использования ORM.См.также
Использование курсоров на стороне сервера (они же потоковые результаты) - пересмотренная документация
Исправлена ошибка в
Result
, когда при использованииConnection.execution_options.stream_results
стратегия буферизованного результата не использовалась, если используемый диалект не поддерживал явную настройку «курсор на стороне сервера». Это ошибочно, поскольку такие DBAPI, как SQLite и Oracle, уже используют небуферизованную схему получения результатов, которая все равно выигрывает от использования частичной выборки результатов. Теперь во всех случаях, когда установлено значениеConnection.execution_options.stream_results
, используется «буферизованная» стратегия.Добавлена функция
FilterResult.yield_per()
, чтобы реализации результата, такие какMappingResult
,ScalarResult
иAsyncResult
, имели доступ к этому методу.References: #8199
sql¶
Внесены изменения в компиляцию SQL для функций конкатенации строк
.contains()
,.startswith()
,.endswith()
, которые заставляют использовать оператор конкатенации строк, а не полагаются на перегрузку оператора сложения, так что нестандартное использование этих операторов, например, с байтстрингами, по-прежнему приводит к операторам конкатенации строк.References: #8253
mypy¶
Исправлено падение плагина mypy при использовании лямбды в качестве Column по умолчанию. Pull request любезно предоставлен tchapi.
References: #8196
asyncio¶
Добавлено
asyncio.shield()
в процесс освобождения соединения и сессии, в частности, в рамках выхода из контекстного менеджера__aexit__()
, при использованииAsyncConnection
илиAsyncSession
в качестве контекстного менеджера, который освобождает объект по завершении работы контекстного менеджера. Это, по-видимому, помогает при отмене задачи при использовании альтернативных библиотек параллелизма, таких какanyio
,uvloop
, которые в противном случае не обеспечивают асинхронный контекст для пула соединений, чтобы корректно освободить соединение при отмене задачи.References: #8145
postgresql¶
Исправлена проблема в диалекте psycopg2, когда функция «multiple hosts», реализованная для #4392, когда в строке запроса можно было передать несколько пар
host:port
в виде?host=host1:port1&host=host2:port2&host=host3:port3
, была реализована некорректно, так как не распространяла должным образом параметр «port». Соединения, в которых не использовался другой «порт», скорее всего, работали без проблем, а соединения, в которых «порт» использовался для некоторых записей, могли некорректно передавать это имя хоста. Теперь формат исправлен таким образом, чтобы передавать хосты/порты должным образом.В рамках этого изменения была сохранена поддержка другого непреднамеренно работавшего стиля мультихостов, который представляет собой формат
?host=h1,h2,h3&port=p1,p2,p3
, разделенный запятыми. Этот формат более соответствует формату строк запросов libpq, в то время как предыдущий формат был вдохновлен другим аспектом формата URI libpq, но не совсем тем же самым.Если эти два стиля смешиваются, то возникает ошибка, так как это неоднозначно.
References: #4392
mssql¶
Исправлены проблемы, из-за которых новые шаблоны использования DML с объектами ORM, представленные в Использование INSERT, UPDATE и ON CONFLICT (т.е. upsert) для возврата объектов ORM, не могли корректно работать с диалектом SQL Server pyodbc.
References: #8210
Исправлена проблема, при которой запрос диалекта SQL Server на текущий уровень изоляции не выполнялся в Azure Synapse Analytics из-за того, что эта база данных обрабатывает откат транзакций после возникновения ошибки. Исходный запрос был изменен таким образом, чтобы больше не полагаться на поимку ошибки при попытке определить соответствующее системное представление. Кроме того, для лучшей поддержки весьма специфического поведения этой базы данных при откате реализован новый параметр
ignore_no_transaction_on_rollback
, указывающий, что при откате следует игнорировать ошибку Azure Synapse „No corresponding transaction found. (111214)», которая возникает в случае отсутствия транзакции в конфликте с Python DBAPI.Первоначальный патч и ценная помощь в отладке были предоставлены @ww2406.
References: #8231
misc¶
Исправлена проблема, при которой оператор
TypeDecorator
некорректно проксировал оператор__getitem__()
при оформлении типа данныхARRAY
, без явного обходного пути.References: #7249
1.4.39¶
Released: June 24, 2022orm¶
Исправлена регрессия, вызванная #8133, когда формат pickle для изменяемых атрибутов был изменен без возврата для распознавания старого формата, что приводило к тому, что при обновлении SQLAlchemy на месте не удавалось прочитать pickle-данные из предыдущих версий. Теперь предусмотрена проверка и возврат к старому формату.
References: #8133
1.4.38¶
Released: June 23, 2022orm¶
Исправлена регрессия, вызванная использованием #8064, когда конкретная проверка соответствия столбцов была слишком либеральной, что приводило к некорректному отображению некоторых ORM-подзапросов, например, использующих
PropComparator.has()
илиPropComparator.any()
в сочетании с запросами с объединенным наследованием, которые также используют унаследованные возможности алиасинга.References: #8162
Исправлена проблема, при которой
GenerativeSelect.fetch()
не применялся при выполнении оператора с использованием ORM.References: #8091
Исправлена проблема, при которой опция
with_loader_criteria()
не могла быть замаринована, что необходимо, когда она передается для распространения в ленивые загрузчики в сочетании со схемой кэширования. В настоящее время единственная форма, которая поддерживается в качестве picklable, - это передача «критерия where» в виде фиксированной вызываемой функции на уровне модуля, которая производит SQL-выражение. Специальная «лямбда» не может быть пикирована, а объект SQL-выражения обычно не является полностью пикируемым напрямую.References: #8109
engine¶
Исправлен декоратор класса, предупреждающий об устаревании, из-за которого ключевые объекты, такие как
Connection
, не имели нужного атрибута__weakref__
, что приводило к ошибкам в операциях типаinspect.getmembers()
стандартной библиотеки Python.References: #8115
sql¶
Исправлено несколько наблюдаемых состояний гонки, связанных с
lambda_stmt()
, включая проблему «собачьей кучи» при первоначальном анализе нового объекта кода Python в нескольких одновременных потоках, которая приводила как к проблемам с производительностью, так и к некоторому внутреннему повреждению состояния. Кроме того, для версий Python до 3.10 было исправлено состояние гонки, которое могло возникнуть при «клонировании» конструкции выражения, находящейся в процессе компиляции или другого доступа в другом потоке, из-за того, что мемоизированные атрибуты изменяли__dict__
во время итерации; в частности, к этому чувствительна конструкция lambda SQL, поскольку она постоянно хранит один объект выражения. Итерация была доработана таким образом, чтобы вместо нее использоваласьdict.copy()
с дополнительной итерацией или без нее.References: #8098
Усовершенствован механизм
Cast
и других «оборачивающих» конструкций столбцов для более полного сохранения обернутой конструкцииLabel
, в том числе для сохранения имени метки в коллекции.c
вSubquery
. Метка уже могла корректно отображаться в SQL на внешней стороне конструкции, в которую она была обернута.References: #8084
Исправлено исправление, сделанное для #8056, которое корректировало экранирование имен связанных параметров со специальными символами таким образом, что экранированные имена транслировались после шага компиляции SQL, что нарушало опубликованный в FAQ рецепт, иллюстрирующий объединение имен параметров в строковый вывод скомпилированной SQL-строки. Данное изменение восстанавливает экранированные имена, поступающие из
compiled.params
, и добавляет условный параметр кSQLCompiler.construct_params()
с именемescape_names
, который по умолчанию принимает значениеTrue
, восстанавливая старое поведение по умолчанию.References: #8113
schema¶
Исправлены ошибки, связанные с параметрами
Table.include_columns
иTable.resolve_fks
наTable
; эти малоиспользуемые параметры не работали для столбцов, ссылающихся на ограничения внешнего ключа.В первом случае невключенные столбцы, ссылающиеся на внешние ключи, все равно будут пытаться создать объект
ForeignKey
, выдавая ошибки при попытке разрешить столбцы для ограничения внешнего ключа в рамках рефлексии; теперь ограничения внешнего ключа, ссылающиеся на пропущенные столбцы, исключаются из процесса рефлексии таблицы так же, как это происходит для объектовIndex
иUniqueConstraint
с теми же условиями. При этом предупреждение не выдается, так как в версии 2.0 мы, скорее всего, захотим убрать предупреждения include_columns для всех ограничений.В последнем случае создание псевдонимов таблиц или подзапросов заканчивалось неудачей, если не была найдена связанная таблица FK, несмотря на наличие
resolve_fks=False
; логика была исправлена таким образом, что если связанная таблица не найдена, объектForeignKey
по-прежнему проксируется в псевдонимы таблицы или подзапроса (эти объектыForeignKey
обычно используются при создании условий присоединения), но он отправляется с флагом, что он не разрешаем. После этого алиасированная таблица/подзапрос будет работать нормально, за исключением того, что она не может быть использована для автоматической генерации условия присоединения, поскольку информация о внешнем ключе отсутствует. Подобное поведение уже было характерно для ограничений с внешним ключом, созданных с использованием неотражательных методов, например, при объединенииTable
объектов из разныхMetaData
коллекций.Исправлена проблема, при которой объекты
Table
, использующие столбцы IDENTITY с типом данныхNumeric
, выдавали ошибки при попытке согласования столбца «autoincrement», не позволяя построитьColumn
с использованием параметраColumn.autoincrement
, а также выдавали ошибки при попытке вызвать конструкциюInsert
.References: #8111
extensions¶
1.4.37¶
Released: May 31, 2022orm¶
Исправлена проблема, при которой использование конструкции
column_property()
, содержащей подзапрос к уже отображенному атрибуту столбца, некорректно применяло поведение ORM-компиляции к подзапросу, в том числе не включалось выражение «IN», добавленное для выражения «наследование одной таблицы».References: #8064
Исправлена проблема, при которой результаты ORM применяли неверные имена ключей к возвращаемым объектам
Row
в случае изменения набора выбираемых столбцов, например, при использованииSelect.with_only_columns()
.References: #8001
Исправлена ошибка, вероятно, регрессия из 1.3, когда использование имен столбцов, требующих экранирования связанных параметров, в частности, при использовании Oracle с именами столбцов, требующих кавычек, например, начинающихся с символа подчеркивания, или в менее распространенных случаях в некоторых драйверах PostgreSQL при использовании имен столбцов, содержащих знаки процента, приводило к некорректной работе функции версионности ORM, если сам столбец версионности имел такое имя, поскольку ORM предполагал определенные соглашения об именовании связанных параметров, в которые вмешивались кавычки. Данный выпуск связан с #8053 и по существу пересматривает подход к устранению этой проблемы, пересматривая исходный выпуск #5653, в котором была создана первоначальная реализация обобщенного цитирования имен связанных параметров.
References: #8056
engine¶
sql¶
Исправлена ошибка, при которой метод PostgreSQL
Insert.on_conflict_do_update()
и метод SQLiteInsert.on_conflict_do_update()
не могли корректно разместить столбец с отдельным «.key» при указании столбца по имени ключа в словаре, передаваемом вInsert.on_conflict_do_update.set_
, а также при использовании коллекцииInsert.excluded
непосредственно в качестве словаря.References: #8014
Информационная ошибка возникает в случае, когда
Insert.from_select()
передается объект «compound select», например, UNION, а в оператор INSERT необходимо добавить дополнительные столбцы для поддержки Python- или явных SQL-установок из метаданных таблицы. В этом случае необходимо передать подзапрос составного объекта.References: #8073
Исправлена проблема, при которой использование
bindparam()
без явного указания данных или типа могло приводить к неправильному типу при использовании в выражениях, например, при использованииComparator.any()
иComparator.all()
.References: #7979
Если два отдельных объекта
BindParameter
имеют одинаковое имя, но один из них используется в «расширяющем» контексте (обычно в выражении IN), а другой - нет, то возникает информационная ошибка; смешение одного и того же имени в этих двух различных стилях использования не поддерживается, и обычно параметрexpanding=True
должен быть установлен для параметров, которые должны получать списочные значения вне выражений IN (гдеexpanding
установлен по умолчанию).References: #8018
mysql¶
Дальнейшая корректировка диалекта MySQL PyODBC для обеспечения полного подключения, которое ранее не работало, несмотря на исправления в #7871.
References: #7966
Добавлен код отключения для ошибки MySQL 4031, появившейся в MySQL >= 8.0.24 и указывающей на превышение таймаута ожидания соединения. В частности, это исправляет проблему, когда предварительный пинг не мог восстановить соединение при превышении таймаута. Pull request любезно предоставлен valievkarim.
References: #8036
mssql¶
oracle¶
Добавлены два новых кода ошибок для обработки отсоединения Oracle для поддержки раннего тестирования нового драйвера «python-oracledb», выпущенного Oracle.
References: #8066
Исправлена проблема компилятора SQL, когда функция «bind processing» для связанного параметра некорректно применялась к связанному значению, если имя связанного параметра было «экранировано». Конкретно это относится, в частности, к Oracle, когда
Column
имеет имя, которое само по себе требует кавычек, так что требующее кавычек имя затем используется для связанных параметров, генерируемых в операторах DML, а используемый тип данных требует обработки связывания, например, типEnum
.References: #8053
1.4.36¶
Released: April 26, 2022orm¶
Исправлена регрессия, при которой изменение, внесенное в конструкцию #7861, выпущенную в версии 1.4.33, в результате которого конструкция
Insert
стала частично распознаваться как оператор с поддержкой ORM, не передавало корректное состояние mapper / mapped table вSession
, что приводило к ошибке методаSession.get_bind()
дляSession
, который был связан с движками и/или соединениями с помощью параметраSession.binds
.References: #7936
orm declarative¶
Модифицирован метакласс
DeclarativeMeta
для передачиcls.__dict__
в процесс декларативного сканирования для поиска атрибутов, а не в отдельный словарь, передаваемый в метод__init__()
типа. Это позволяет пользовательским базовым классам, добавляющим атрибуты в__init_subclass__()
, работать так, как ожидалось, поскольку__init_subclass__()
может влиять только на самcls.__dict__
, а не на другой словарь. Технически это является регрессом по сравнению с 1.3, где использовался метод__dict__
.References: #7900
engine¶
Исправлена утечка памяти в расширениях C, которая могла возникать при обращении к именованным членам
Row
, когда член не существовал в Python 3; в частности, это могло происходить при преобразованиях NumPy, когда он пытался вызвать такие члены, как.__array__
, но проблема была связана с любымиAttributeError
, выброшенными объектомRow
. Эта проблема не относится к версии 2.0, которая уже перешла на Cython. Большое спасибо Себастьяну Бергу за выявление проблемы.References: #7875
Добавлено предупреждение об ошибке, возникающей в методе
Result.columns()
при передаче 0 в качестве индекса в сочетании сResult
, который возвращает одну сущность ORM, что указывает на то, что текущее поведениеResult.columns()
в этом случае нарушено, поскольку объектResult
будет выдавать скалярные значения, а не объектыRow
. Эта проблема будет исправлена в версии 2.0, что будет являться обратно несовместимым изменением для кода, который полагается на текущее нарушенное поведение. Код, желающий получить коллекцию скалярных значений, должен использовать методResult.scalars()
, который вернет новый объектScalarResult
, выдающий нерядные скалярные объекты.References: #7953
schema¶
Исправлена ошибка, при которой соглашения об именовании
ForeignKeyConstraint
, использующие ключreferred_column_0
, не работали, если ограничение внешнего ключа было задано как объектForeignKey
, а не как явный объектForeignKeyConstraint
. Поскольку данное изменение использует обратный перенос некоторых исправлений из версии 2.0, также исправлена дополнительная малоизвестная особенность, которая, вероятно, была нарушена в течение многих лет, а именно: объектForeignKey
может ссылаться на ссылающуюся таблицу только по имени таблицы без использования имени столбца, если имя ссылающегося столбца совпадает с именем ссылающегося столбца.Ключ именования
referred_column_0
ранее не тестировался с объектомForeignKey
, толькоForeignKeyConstraint
, и эта ошибка показывает, что функция никогда не работала корректно, еслиForeignKeyConstraint
не использовался для всех ограничений FK. Эта ошибка восходит к первоначальному внедрению функции, введенной для #3989.References: #7958
asyncio¶
Исправлена работа с объектами
contextvar.ContextVar
внутри асинхронных адаптированных обработчиков событий. Ранее значения, применяемые к объектуContextVar
, не распространялись в конкретном случае вызова ожидаемых объектов внутри не ожидаемого кода.References: #7937
postgresql¶
Исправлена ошибка в типе данных
ARRAY
в сочетании сEnum
на PostgreSQL, когда использование методов.any()
или.all()
для визуализации SQL ANY() или ALL(), заданных в качестве аргументов членов перечисления Python, приводило к сбою адаптации типов на всех драйверах.References: #6515
Реализован атрибут
UUID.python_type
для объекта типа PostgreSQLUUID
. Атрибут возвращает либоstr
, либоuuid.UUID
в зависимости от настройки параметраUUID.as_uuid
. Ранее этот атрибут был нереализован. Pull request любезно предоставлен Alex Grönholm.References: #7943
Исправлена проблема в диалекте psycopg2 при использовании параметра
create_engine.pool_pre_ping
, которая приводила к случайному сбросу обработчиком «ping» настроенного пользователем уровня изоляцииAUTOCOMMIT
.References: #7930
mysql¶
tests¶
Для диалектов сторонних производителей исправлено недостающее требование к тесту набора
SimpleUpdateDeleteTest
, который не проверял наличие работающей функции «rowcount» на целевом диалекте.References: #7919
1.4.35¶
Released: April 6, 2022sql¶
Исправлена ошибка в недавно реализованной функции
FunctionElement.table_valued.joins_implicitly
, когда при вызове или параметр не распространялся автоматически из исходного объектаTableValuedAlias
во вторичный объект, создаваемый при вызовеTableValuedAlias.render_derived()
илиTableValuedAlias.alias()
.Дополнительно устранены эти проблемы в
TableValuedAlias
:Устранена потенциальная проблема с памятью, которая могла возникнуть при многократном вызове
TableValuedAlias.render_derived()
к последовательным копиям одного и того же объекта (для .alias() в настоящее время приходится продолжать цепочку с предыдущего элемента. не уверен, что это можно улучшить, но это стандартное поведение для .alias() в других местах).Исправлена проблема, когда при вызове
TableValuedAlias.render_derived()
илиTableValuedAlias.alias()
терялись отдельные типы элементов.
References: #7890
Исправлена регрессия, вызванная #7823, которая влияла на систему кэширования, в результате чего связанные параметры, которые были «клонированы» в операциях ORM, таких как полиморфная загрузка, в некоторых случаях не получали своего правильного значения во время выполнения, что приводило к некорректному отображению значений привязки.
References: #7903
1.4.34¶
Released: March 31, 2022orm¶
Исправлена регрессия, вызванная #7861, когда вызов конструкции
Insert
, содержащей сущности ORM, непосредственно черезSession.execute()
приводил к ошибке.References: #7878
postgresql¶
Исправление, сделанное в #6581, когда режим «исполняемых значений» для psycopg2 был отключен для всех стилей INSERT «ON CONFLICT», не распространяется на предложение «ON CONFLICT DO NOTHING», которое не содержит никаких параметров и безопасно для режима «исполняемых значений». «ON CONFLICT DO UPDATE» по-прежнему блокируется от режима «исполняемых значений», поскольку в предложении DO UPDATE могут присутствовать дополнительные параметры, которые не могут быть переданы в пакет (что и было первоначальной проблемой, исправленной в #6581).
References: #7880
1.4.33¶
Released: March 31, 2022orm¶
К функции
with_polymorphic()
добавлена функцияwith_polymorphic.adapt_on_names
, которая позволяет указать полиморфную нагрузку (обычно с конкретным отображением) против альтернативного selectable, который будет адаптироваться к исходному mapped selectable только по именам столбцов.References: #7805
Добавлены новые атрибуты
UpdateBase.returning_column_descriptions
иUpdateBase.entity_description
для проверки атрибутов и сущностей ORM, которые устанавливаются как часть конструкцииInsert
,Update
илиDelete
. АксессорSelect.column_descriptions
теперь реализован и для селекторов, предназначенных только для Core.References: #7861
Исправлена ошибка в стратегии «динамического» загрузчика, когда метод
Query.filter_by()
не получал соответствующей сущности для фильтрации, в случае если в запрашиваемом отношении присутствовала «вторичная» таблица, а отображение было на что-то сложное, например, «с полиморфизмом».References: #7868
Исправлена ошибка, при которой атрибуты
composite()
не работали в сочетании со стратегией загрузчикаselectin_polymorphic()
для наследования объединенных таблиц.References: #7801
Улучшение использования памяти ORM за счет удаления значительного набора промежуточных объектов выражений, которые обычно хранятся при создании копии объекта выражения. Эти клоны были значительно уменьшены, что позволило сократить общее количество объектов выражений, хранящихся в памяти при отображении ORM, примерно на 30%.
References: #7823
Исправлена проблема, при которой опция загрузчика
selectin_polymorphic()
не работала с отображателями объединенного наследования, не имеющими фиксированного столбца «polymorphic_on». Дополнительно добавлена тестовая поддержка более широкого спектра вариантов использования данной конструкции.References: #7799
Исправлена ошибка в функции
with_loader_criteria()
, из-за которой критерии загрузчика не применялись к объединенным eager-загрузкам, которые были вызваны в рамках операции обновления родительского объекта.References: #7862
Исправлена проблема, когда
Mapper
слишком агрессивно уменьшал пользовательский аргументMapper.primary_key
в случае отображения наUNION
, где для некоторых записей SELECT два столбца по сути эквивалентны, а для других - нет, как, например, в рекурсивном CTE. Логика здесь изменена на принятие заданного пользователем PK как заданного, при этом столбцы будут относиться к отображаемому selectable, но уже не «сокращаться», так как эта эвристика не может учесть все ситуации.References: #7842
engine¶
Добавлен новый параметр
Engine.dispose.close
, по умолчанию имеющий значение True. При значении False утилизация движка вообще не трогает соединения в старом пуле, просто сбрасывая пул и заменяя его. Это нужно для того, чтобы при передаче исходного пула от родительского процесса родительский процесс мог продолжать использовать эти соединения.См.также
Использование пулов соединений с многопроцессорной обработкой или os.fork() - пересмотренная документация
Уточнено протоколирование на уровне соединения: сообщения журналов BEGIN, ROLLBACK и COMMIT не указывают на реальную транзакцию, если используется уровень изоляции AUTOCOMMIT; расширен набор сообщений, включающий само сообщение BEGIN, а также исправлена ситуация, когда параметр
Engine
уровняcreate_engine.isolation_level
использовался напрямую.References: #7853
sql¶
Добавлен новый параметр
FunctionElement.table_valued.joins_implicitly
для конструкцииFunctionElement.table_valued()
. Этот параметр указывает на то, что данная таблично-значная функция неявно присоединяется к таблице, на которую она ссылается, что, по сути, исключает действие функции «from linting», т.е. предупреждение о «картезианском произведении», из-за наличия этого параметра. Может использоваться для таких функций, какfunc.json_each()
.References: #7845
Параметр
bindparam.literal_execute
теперь участвует в генерации кэшаbindparam()
, поскольку изменяет sql-строку, генерируемую компилятором. Ранее использовались корректные значения привязки, но при последующих выполнениях одного и того же запроса параметрliteral_execute
игнорировался.References: #7876
Исправлена регрессия, вызванная #7760, когда новые возможности
TextualSelect
не были полностью реализованы в компиляторе, что приводило к проблемам с составными конструкциями INSERT, такими как «INSERT FROM SELECT» и «INSERT…ON CONFLICT», в сочетании с CTE и текстовыми операторами.References: #7798
schema¶
Добавлена поддержка того, что вызываемая функция
Table.to_metadata.referred_schema_fn
, передаваемая вTable.to_metadata()
, может возвращать значениеBLANK_SCHEMA
, указывающее на то, что ссылаемый внешний ключ должен быть сброшен в None. Также из этой функции может быть возвращен символRETAIN_SCHEMA
для указания на «отсутствие изменений», который будет вести себя так же, как иNone
, который также указывает на отсутствие изменений.References: #7860
sqlite¶
Исправлена ошибка, при которой имя ограничений CHECK под SQLite не отражалось, если имя было создано с использованием кавычек, как это бывает, когда в имени используется смешанный регистр или специальные символы.
References: #5463
mssql¶
misc¶
Улучшено сообщение об ошибке, выдаваемое в случае, когда конструкция
association_proxy()
пытается получить доступ к целевому атрибуту на уровне класса, и этот доступ оказывается неудачным. В данном случае речь идет о проксировании к гибридному атрибуту, не имеющему рабочей реализации на уровне класса.References: #7827
1.4.32¶
Released: March 6, 2022orm¶
Исправлена ошибка, при которой ORM-исключение, которое должно быть вызвано, когда INSERT молча не может вставить строку (например, из триггера), не достигалось из-за опережающего исключения, вызванного отсутствием значения первичного ключа, что приводило к неинформативному исключению, а не к корректному. В версии 1.4 и выше для этого случая добавлено новое исключение
FlushError
, которое поднимается раньше, чем предыдущее исключение «null identity» в версии 1.3, поскольку ситуация, когда количество реально вводимых строк не соответствует ожидаемому, является более критичной в версии 1.4, так как мешает корректной работе пакетной обработки нескольких объектов. Это не относится к ситуации, когда только что полученный первичный ключ получен как NULL, что продолжает вызывать существующее исключение «null identity».References: #7594
Исправлена проблема, при которой использование полного пути для имени класса в
relationship()
, который, тем не менее, содержал неправильное имя для токенов пути, не являющихся первым токеном, не приводило к возникновению информативной ошибки, а приводило к случайному отказу на последующем шаге.References: #7697
engine¶
Настроено протоколирование для ключевых компонентов SQLAlchemy, включая
Engine
,Connection
, для установки соответствующего параметра уровня стека, чтобы токены протоколирования PythonfuncName
иlineno
при использовании в пользовательских форматерах протоколирования выдавали корректную информацию, что может быть полезно при фильтрации вывода журнала; поддерживается на Python 3.8 и выше. Pull request любезно предоставлен Маркусом Герстелем.References: #7612
sql¶
Исправлены сообщения об ошибках, связанных с типами, которые не срабатывали для значений, являющихся кортежами, из-за синтаксиса форматирования строк, включая компиляцию неподдерживаемых литеральных значений и недопустимых булевых значений.
References: #7721
Исправлены проблемы с типами данных MySQL
SET
и общим типом данныхEnum
, когда метод__repr__()
не выводил все необязательные параметры в строковый вывод, что влияло на использование этих типов в автогенерации Alembic. Pull request для MySQL любезно предоставлен Yuki Nishimine.Тип данных
Enum
теперь выдает предупреждение, если аргументEnum.length
указан без указания параметраEnum.native_enum
как False, так как в противном случае параметр будет молча игнорироваться, несмотря на то, что тип данныхEnum
все равно будет отображать VARCHAR DDL на бэкендах, не имеющих собственного типа данных ENUM, таких как SQLite. Возможно, в будущем это поведение изменится, и «длина» будет учитываться для всех неродных типов «enum» независимо от настройки «native_enum».Исправлена проблема, при которой метод
HasCTE.add_cte()
, вызываемый на экземпляреTextualSelect
, не учитывался компилятором SQL. Исправление дополнительно добавляет более «SELECT»-подобное поведение компилятора дляTextualSelect
, в том числе позволяет учитывать DML CTE, такие как UPDATE и INSERT.References: #7760
asyncio¶
Исправлена проблема, при которой не выдавалось описательное сообщение об ошибке для некоторых классов событий, прослушиваемых с помощью механизма async, который вместо этого должен быть экземпляром механизма sync.
Исправлена проблема, при которой метод
AsyncSession.execute()
не вызывал информативного исключения, если использовалась опция выполненияConnection.execution_options.stream_results
, несовместимая с объектомResult
в стиле синхронизации при использовании стиля вызова asyncio, так как операцию получения большего количества строк необходимо было ожидать. Теперь в этом случае возникает исключение, аналогичное тому, которое уже возникало при использовании опцииConnection.execution_options.stream_results
с методомAsyncConnection.execute()
.Кроме того, для повышения стабильности работы с драйверами баз данных, чувствительными к состоянию, такими как asyncmy, курсор теперь закрывается при возникновении этого состояния ошибки; ранее при использовании диалекта asyncmy соединение переходило в недействительное состояние с сохранением неиспользованных результатов на стороне сервера.
References: #7667
postgresql¶
Добавлена поддержка компилятором фразы PostgreSQL
NOT VALID
при выводе DDL для конструкций схемCheckConstraint
,ForeignKeyConstraint
иForeignKey
. Pull request любезно предоставлен Гилбертом Гилбсом.См.также
References: #7600
mysql¶
Исправлена регрессия, вызванная #7518, когда изменение синтаксиса «SHOW VARIABLES» на «SELECT @@» нарушало совместимость с версиями MySQL старше 5.6, включая ранние версии 5.0. Несмотря на то, что это очень старые версии MySQL, изменение совместимости не планировалось, поэтому была восстановлена специфическая для каждой версии логика возврата к «SHOW VARIABLES» для версий сервера MySQL < 5.6.
References: #7518
mariadb¶
Исправлена ошибка в диалекте mariadbconnector начиная с версии mariadb connector 1.0.10, когда DBAPI переставал предварительно буферизовать cursor.lastrowid, что приводило к ошибкам при вставке объектов с помощью ORM, а также к недоступности атрибута
CursorResult.inserted_primary_key
. Теперь диалект получает это значение проактивно для ситуаций, когда оно применимо.References: #7738
sqlite¶
Добавлена поддержка отражения встроенных уникальных ограничений SQLite, в которых имена столбцов оформлены с помощью «спасательных кавычек» SQLite
[]
или`
, которые отбрасываются базой данных при формировании имени столбца.References: #7736
Исправлена проблема, когда при отражении уникальных ограничений SQLite не удавалось обнаружить встроенное в столбец ограничение UNIQUE, если в имени столбца присутствовал символ подчеркивания.
References: #7736
oracle¶
Исправлена проблема в диалекте Oracle, когда при использовании имени столбца, требующего кавычек при записи в качестве связанного параметра, например
"_id"
, некорректно отслеживалось значение по умолчанию, сгенерированное в Python, из-за отсутствия этого значения при переписывании связанного параметра, что приводило к возникновению ошибки Oracle.References: #7676
Добавлена поддержка разбора кодов ошибок «DPI» из объектов исключений cx_Oracle, таких как
DPI-1080
иDPI-1010
, которые, начиная с версии cx_Oracle 8.3, указывают на сценарий разъединения.References: #7748
tests¶
Улучшена интеграция тестового пакета с pytest, в результате чего плагин «warnings», если он включен вручную, не будет мешать работе тестового пакета. Таким образом, сторонние разработчики могут включить плагин warnings или использовать параметр
-W
, а тестовый пакет SQLAlchemy будет продолжать работать. Кроме того, модернизировано обнаружение плагина «pytest-xdist», так что плагины могут быть глобально отключены с помощью PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 без нарушения работы тестового набора, если xdist все еще установлен. Фильтры предупреждений, переводящие предупреждения об устаревании в ошибки, теперь локализованы на предупреждения, специфичные для SQLAlchemy, или на источники, специфичные для SQLAlchemy, для общих предупреждений об устаревании Python, так что предупреждения об устаревании, выдаваемые плагинами pytest, не относящимися к SQLAlchemy, также не должны влиять на тестовый набор.References: #7599
Внесены исправления в стандартную конфигурацию pytest, касающиеся настройки обнаружения тестов, для устранения проблемы, когда тестовый набор не мог правильно настроить предупреждения, а также пытался загрузить наборы примеров в качестве тестов, в конкретном случае, когда проверка SQLAlchemy располагалась в абсолютном пути, который имел суперкаталог с именем «test».
References: #7045
1.4.31¶
Released: January 20, 2022orm¶
Исправлена проблема в
Session.bulk_save_objects()
, когда сортировка, происходящая при установке параметраpreserve_order
в значение False, частично сортировала объектыMapper
, что в Python 3.11 отвергается.References: #7591
postgresql¶
mysql¶
mssql¶
Добавлена поддержка
FILESTREAM
при использованииVARBINARY(max)
в MSSQL.См.также
VARBINARY.filestream
References: #7243
1.4.30¶
Released: January 19, 2022orm¶
Исправлена проблема загрузки дополнительных атрибутов при глубоком многоуровневом наследовании, когда промежуточная таблица, не содержащая столбцов, не включалась в объединяемые таблицы, а связывала эти таблицы с их идентификаторами первичных ключей. Хотя это работает нормально, тем не менее, в версии 1.4 это стало приводить к предупреждению компилятора о картезианском произведении. Логика была изменена таким образом, чтобы эти промежуточные таблицы включались независимо от этого. Хотя при этом в запрос включаются дополнительные таблицы, которые технически не нужны, это происходит только в очень необычном случае глубокого наследования 3+ уровня с промежуточными таблицами, не имеющими столбцов, не являющихся первичными ключами, поэтому ожидается, что потенциальное влияние на производительность будет пренебрежимо мало.
References: #7507
Исправлена проблема, когда при вызове функции
registry.map_imperatively()
более одного раза для одного и того же класса выдавалась неожиданная ошибка, а не информативное сообщение о том, что целевой класс уже отображен. Такое поведение отличалось от поведения функцииmapper()
, которая действительно выдает информативное сообщение.References: #7579
В класс
AsyncSession
добавлен недостающий методAsyncSession.invalidate()
.References: #7524
Исправлена регрессия, появившаяся в 1.4.23, которая в некоторых случаях приводила к неправильной обработке опций загрузчика, в частности, при использовании наследования объединенных таблиц в сочетании с опцией
polymorphic_load="selectin"
, а также ленивой загрузки отношений, что приводило к ошибкеTypeError
.References: #7557
Исправлена регрессия ORM, при которой вызов функции
aliased()
на существующую конструкциюaliased()
приводил к некорректному SQL, если существующая конструкция была направлена на фиксированную таблицу. Исправление позволяет не учитывать исходную конструкциюaliased()
, если она была предназначена только для таблицы, которая теперь заменяется. Также исправление позволяет корректно вести себя при построенииaliased()
без выбираемого аргумента противaliased()
, который направлен против подзапроса, для создания псевдонима этого подзапроса (т.е. для изменения его имени).Поведение вложенности
aliased()
сохраняется и для случая, когда внешний объектaliased()
обращается к подзапросу, который, в свою очередь, ссылается на внутренний объектaliased()
. Это относительно новое свойство версии 1.4, которое позволяет удовлетворить потребности тех случаев, которые ранее обслуживались устаревшим методомQuery.from_self()
.References: #7576
Исправлена проблема, когда метод
Select.correlate_except()
при передаче значенияNone
или отсутствии аргументов не коррелировал ни с одним элементом при использовании в контексте ORM (то есть при передаче сущностей ORM в качестве предложений FROM), а не приводил к тому, что все элементы FROM считались «коррелированными», как это происходит при использовании конструкций, предназначенных только для Core.References: #7514
Исправлена регрессия из 1.3, при которой стратегия загрузчика «subqueryload» при использовании в запросе, использующем
Query.from_statement()
илиSelect.from_statement()
, приводила к ошибке с трассировкой стека. Поскольку загрузка подзапроса требует модификации исходного оператора, она несовместима с вариантом использования «from_statement», особенно для запросов, составленных с использованием конструкцииtext()
. Теперь поведение эквивалентно поведению в версии 1.3 и более ранних версиях, которое заключается в том, что стратегия загрузчика тихо деградирует и не используется для таких операторов, обычно возвращаясь к использованию стратегии lazyload.References: #7505
sql¶
В систему, определяющую реализации
TypeEngine
из литералов Python, добавлено дополнительное правило для применения второго уровня настройки типа, так что Python datetime с tzinfo или без него может задавать параметрtimezone=True
у возвращаемого объектаDateTime
, а такжеTime
. Это помогает при некоторых сценариях обхода в чувствительных к типу диалектах PostgreSQL, таких как asyncpg, psycopg3 (только в версии 2.0).References: #7537
Добавлено информативное сообщение об ошибке при передаче объекта метода в SQL-конструкцию. Ранее при передаче таких вызываемых объектов, что является распространенной типографской ошибкой при работе с SQL-конструкциями, связанными с методами, они интерпретировались как цели «лямбда SQL», которые должны быть вызваны во время компиляции, что приводило к тихим сбоям. Поскольку данная возможность не предназначалась для использования с методами, объекты методов теперь отвергаются.
References: #7032
mypy¶
Исправлено падение Mypy при работе в режиме демона id, вызванное отсутствием атрибута у внутреннего экземпляра mypy
Var
.References: #7321
asyncio¶
В интерфейс соединений DBAPI, используемый драйверами asyncio, добавлен новый метод
AdaptedConnection.run_async()
, позволяющий вызывать методы к базовому соединению «драйвера» непосредственно в функции стиля sync, где нельзя использовать ключевое словоawait
, например, в функции обработчика событий SQLAlchemy. Метод аналогичен методуAsyncConnection.run_sync()
, который переводит вызовы в стиле async в вызовы в стиле sync. Этот метод полезен для таких вещей, как обработчики соединения-пула on-connect, которым необходимо вызывать ожидающие методы на соединении драйвера при его первом создании.References: #7580
postgresql¶
В тип данных
UUID
добавлено отображение строк, так что при строковой обработке оператора с «literal_binds», использующего этот тип, будет получено соответствующее строковое значение для бэкенда PostgreSQL. Pull request любезно предоставлен José Duarte.References: #7561
Улучшена поддержка asyncpg-обработки TIME WITH TIMEZONE, которая была реализована не полностью.
References: #7537
Исправлено отражение покрывающих индексов, в результате чего в словаре отраженных индексов в качестве части записи
dialect_options
сообщаетсяinclude_columns
, что позволяет завершить цикл отражение->создание. Для обратной совместимости включенные столбцы продолжают присутствовать и под ключомinclude_columns
.References: #7382
Исправлена работа с массивами значений перечислений, требующих использования управляющих символов.
References: #7418
mysql¶
Заменить оператор
SHOW VARIABLES LIKE
на эквивалентныйSELECT @@variable
в инициализации диалектов MySQL и MariaDB. Это позволит избежать борьбы за мьютекс, вызываемой операторомSHOW VARIABLES
, и повысить производительность инициализации.References: #7518
Удалена ненужная зависимость от PyMySQL из диалекта asyncmy. Pull request courtesy long2ice.
References: #7567
1.4.29¶
Released: December 22, 2021orm¶
Добавлен параметр
Session.get.execution_options
, который ранее отсутствовал в методеSession.get()
.References: #7410
Исправлена проблема в новом методе «критерии загрузчика»
PropComparator.and_()
, когда при использовании стратегии загрузчика типаselectinload()
против столбца, являющегося членом коллекции.c.
объекта подзапроса, где подзапрос динамически добавляется в предложение FROM оператора, в кэше SQL-операторов появлялись устаревшие значения параметров в подзапросе, так как процесс, используемый стратегией загрузчика для замены параметров во время выполнения, не мог учесть подзапрос при получении его в таком виде.References: #7489
Исправлено рекурсивное переполнение, которое могло возникать при компиляции операторов ORM при использовании функции
with_loader_criteria()
или методаPropComparator.and_()
в стратегии загрузчика в сочетании с подзапросом, который ссылался на одну и ту же сущность, изменяемую параметром критериев или загружаемую стратегией загрузчика. Для учета этого сценария добавлена проверка на рекурсивную встречу с одним и тем же вариантом критериев загрузчика.References: #7491
Исправлена проблема, когда метод
__class_getitem__()
сгенерированного декларативного базового класса поas_declarative()
приводил к недоступности атрибутов класса, таких как__table__
, для случаев, когда в иерархии классов использовалось объявление типов в стилеGeneric[T]
. Это является продолжением базового добавления__class_getitem__()
в #7368. Pull request любезно предоставлен Каем Мюллером.Исправлена проблема, связанная с кэшированием, при которой использование опции загрузчика вида
lazyload(aliased(A).bs).joinedload(B.cs)
не приводило к вызову объединенной загрузки для запусков, следующих за кэшированием запроса, из-за несоответствия опций / пути к объекту, применяемых к объектам, загружаемым для запроса с ведущей сущностью, в котором использовалась опцияaliased()
.References: #7447
engine¶
Исправлено сообщение об ошибке для
AttributeError
, возникающей при попытке записи в атрибут классаRow
, который является неизменяемым. В предыдущем сообщении утверждалось, что столбец не существует, что вводило в заблуждение.References: #7432
Исправлена регрессия в функции
make_url()
, используемой для разбора строк URL, когда при использовании строки Python 2u''
при разборе строки запроса происходило переполнение рекурсии.References: #7446
mypy¶
Исправлена регрессия в mypy, когда в релизе mypy 0.930 были добавлены дополнительные внутренние проверки формата «именованных типов», требующие, чтобы они были полностью квалифицированными и локализуемыми. Это нарушало работу плагина mypy для SQLAlchemy, вызывая ошибку утверждения, поскольку в нем использовались символы
__builtins__
и другие нелокализуемые или неквалифицированные имена, которые ранее не вызывали никаких утверждений.References: #7496
asyncio¶
Добавлена функция
async_engine_config()
для создания асинхронного движка из диктанта конфигурации. В остальном она ведет себя так же, как иengine_from_config()
.References: #7301
mariadb¶
Исправлены классы ошибок, проверяемые при проверке «is_disconnect» для диалекта
mariadbconnector
, который не справлялся с отключениями, происходящими из-за распространенных кодов ошибок MySQL/MariaDB, таких как 2006; в настоящее время DBAPI использует класс исключенийmariadb.InterfaceError
для ошибок отключения, таких как код ошибки 2006, который был добавлен в список проверяемых классов.References: #7457
tests¶
Исправлена регрессия в тестовом наборе, когда тест с именем
CompareAndCopyTest::test_all_present
на некоторых платформах не выполнялся из-за обнаружения дополнительных артефактов тестирования. Pull request любезно предоставлен Nils Philippsen.References: #7450
1.4.28¶
Released: December 9, 2021platform¶
Python 3.10 отказался от использования «distutils» в пользу явного использования «setuptools» в PEP 632; setup.py SQLAlchemy соответствующим образом заменил импорт. Однако, поскольку сам setuptools только недавно добавил символы, упомянутые в pep-632, в ноябре 2021 года в версии 59.0.1,
setup.py
по-прежнему имеет обратный импорт к distutils, поскольку SQLAlchemy 1.4 не имеет жесткого требования к версионности setuptools в настоящее время. Ожидается, что в SQLAlchemy 2.0 будет использоваться полная схема установки PEP 517, которая будет указывать на соответствующую версионность setuptools.References: #7311
orm¶
Исправлена проблема, при которой внутреннее клонирование, используемое методом
PropComparator.any()
наrelationship()
в случае, когда связанный класс также использует полиморфную загрузку ORM, заканчивалось неудачей, если в качестве критерия для операцииany()
использовалось гибридное свойство связанного полиморфного класса.References: #7425
Исправлена проблема, при которой декоратор
as_declarative()
и аналогичные функции, используемые для генерации декларативного базового класса, не копировали метод__class_getitem__()
из заданного суперкласса, что не позволяло использовать pep-484 дженерики в сочетании с классомBase
. Pull request любезно предоставлен Каем Мюллером.References: #7368
Исправлена регрессия ORM, когда новое поведение «eager loaders run on unexpire», добавленное в #1763, приводило к тому, что ошибки опций загрузчика возникали неадекватно в случае, когда один
Query
илиSelect
использовался для загрузки нескольких типов сущностей, вместе с опциями загрузчика, которые применяются только к одному из этих типов сущностей, например,joinedload()
, а затем объекты обновляются по истечении срока действия, где опции загрузчика пытаются быть применены к несоответствующему типу объекта и затем вызывают исключение. Теперь проверка на это несоответствие обходится без выдачи ошибки в этом случае.References: #7318
Определяемые пользователем опции ORM, такие как те, что показаны в примере dogpile.caching, являющиеся подклассом
UserDefinedOption
, по определению обрабатываются при каждом выполнении оператора и не должны рассматриваться как часть ключа кэша для данного оператора. Кэширование базового классаExecutableOption
было изменено таким образом, что он больше не является непосредственно подклассомHasCacheKey
, так что наличие определяемых пользователем объектов опций не будет иметь нежелательного побочного эффекта в виде отключения кэширования утверждений. Теперь в системе кэширования участвуют только специфические для ORM опции загрузчика и критериев, которые являются внутренними для SQLAlchemy.References: #7394
Исправлена проблема, при которой связки, использующие
synonym()
и потенциально другие виды «прокси» атрибутов, не во всех случаях успешно генерировали ключ кэша для своих SQL-операторов, что приводило к снижению производительности этих операторов.References: #7394
Исправлена проблема, при которой список, отображенный с помощью
relationship()
, попадал в бесконечный цикл при in-place добавлении к себе, т.е. при использовании оператора+=
, а также при использовании.extend()
в том же списке.References: #7389
commit
при использовании менеджера контекста дляSession.begin()
происходила попытка отката, которая была невозможна, так какSession
находился между фиксацией транзакции и возвратом соединения в пул, вызывая исключение «this sessiontransaction is in the committed state». Это исключение может возникнуть в основном в контексте asyncio, где может быть вызвана ошибка CancelledError.References: #7388
Отменен недокументированный синтаксис опций загрузчика
".*"
, который, судя по всему, ничем не отличается от передачи одной звездочки, и при его использовании будет выдаваться предупреждение об устаревании. Возможно, этот синтаксис для чего-то и предназначался, но в настоящее время в нем нет необходимости.References: #4390
engine¶
sql¶
Методы «Compound select», такие как
Select.union()
,Select.intersect_all()
и т.д., теперь принимают в качестве аргумента*other
, а неother
, что позволяет объединять с родительским оператором сразу несколько дополнительных SELECT. В частности, изменения, внесенные вCTE.union()
иCTE.union_all()
, позволяют создавать так называемые «нелинейные CTE» с помощью конструкцииCTE
, тогда как ранее не было возможности иметь более двух подэлементов CTE в UNION вместе и при этом корректно обращаться к CTE рекурсивным способом. Pull request любезно предоставлен Эриком Массераном.References: #7259
Поддержка нескольких элементов клаузулы в методе
Exists.where()
, унификация api с тем, что представляет обычная конструкцияselect()
.References: #7386
Расширение атрибута
TypeDecorator.cache_ok
и соответствующего предупреждающего сообщения, если этот флаг не определен, поведение, впервые установленное дляTypeDecorator
как часть #6436, также имеет место дляUserDefinedType
, путем обобщения флага и соответствующей логики кэширования на новую общую базу для этих двух типов,ExternalType
, для созданияUserDefinedType.cache_ok
.Это изменение означает, что любое текущее значение
UserDefinedType
теперь приведет к тому, что кэширование SQL-операторов, использующих этот тип данных, не будет выполняться, а также будет выдаваться предупреждение, если только класс не определит флагUserDefinedType.cache_ok
как True. Если тип данных не может сформировать детерминированный, хешируемый ключ кэша из своих аргументов, то атрибут может быть установлен в значение False, что приведет к отключению кэширования, но подавит предупреждение. В частности, для пользовательских типов данных, используемых в таких пакетах, как SQLAlchemy-utils, необходимо установить этот флаг. Проблема наблюдалась в результате использования в SQLAlchemy-utils типа данных, который в настоящее время не может быть кэширован.См.также
References: #7319
Пользовательские SQL-элементы, диалекты сторонних разработчиков, пользовательские или сторонние типы данных будут выдавать соответствующие предупреждения, если они явно не согласны с кэшированием SQL-операторов, что достигается путем установки соответствующих атрибутов для каждого типа класса. Предупреждение содержит ссылки на разделы документации, в которых указывается, какой подход следует использовать для каждого типа объектов, чтобы включить кэширование.
References: #7394
Исправлены недостающие директивы кэширования для нескольких малоиспользуемых классов в SQL Core, которые приводили к тому, что для элементов, использующих эти классы, в журнал заносилось
[no key]
.References: #7394
mypy¶
Исправлен сбой в работе Mypy, возникавший при использовании плагина Mypy в коде, использующем методы
declared_attr
для не отображаемых имен, таких как__mapper_args__
,__table_args__
или других имен, так как плагин пытался интерпретировать их как отображаемые атрибуты, которые впоследствии неправильно обрабатывались. В рамках этого изменения декорированная функция по-прежнему преобразуется плагином в общий оператор присваивания (например,__mapper_args__: Any
), так что сигнатура аргумента может быть аннотирована так же, как и для любого другого@classmethod
, без жалоб Mypy на неправильный тип аргумента для метода, который не является явно@classmethod
.References: #7321
postgresql¶
tests¶
Реализована поддержка корректной работы тестового набора под Pytest 7. Ранее для Python 3 поддерживался только Pytest 6.x, однако эта версия не была привязана к верхней границе в tox.ini. Pytest не привязан в tox.ini к версии ниже 8, так что версии SQLAlchemy, выпущенные с текущей кодовой базой, смогут быть протестированы под tox без изменений в окружении. Большое спасибо разработчикам Pytest за помощь в решении этой проблемы.
1.4.27¶
Released: November 11, 2021orm¶
Исправлена ошибка в функции «отношение к псевдоклассу», введенная в Взаимосвязь с классом Aliased, когда нельзя было создать вариант стратегии загрузчика, нацеленный на атрибут цели с помощью конструкции
aliased()
непосредственно во втором варианте загрузчика, напримерselectinload(A.aliased_bs).joinedload(aliased_b.cs)
, без явной квалификации с помощьюPropComparator.of_type()
на предыдущем элементе пути. Кроме того, обращение непосредственно к несглаженному классу принималось (неадекватно), но при этом молчаливо завершалось, например,selectinload(A.aliased_bs).joinedload(B.cs)
; теперь это приводит к ошибке, связанной с несоответствием типов.References: #7224
Теперь все объекты
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.References: #7274
Исправлена регрессия 1.4, при которой
Query.filter_by()
некорректно функционировал наQuery
, полученном изQuery.union()
,Query.from_self()
и т.п.References: #7239
Исправлена проблема, при которой отложенная полиморфная загрузка атрибутов из подкласса наследования объединенной таблицы не могла корректно заполнить атрибут, если для первоначального исключения этого атрибута использовалась опция
load_only()
в случае, когда load_only спускался из опции загрузчика отношений. Исправление позволяет другим допустимым опциям, таким какdefer(..., raiseload=True)
и т.д., продолжать работать как положено.References: #7304
Исправлена ошибка версии 1.4, при которой
Query.filter_by()
некорректно функционировал, когдаQuery.join()
присоединялся к сущности, которая использовалаPropComparator.of_type()
для указания псевдослучайной версии целевой сущности. Проблема также относится к ORM-запросам будущего стиля, построенным с использованиемselect()
.References: #7244
engine¶
Исправлена проблема в будущем объекте
Connection
, когда методConnection.execute()
не принимал в качестве словаря параметров объект отображения без дикта, например, собственный объект SQLAlchemyRowMapping
или другой объектabc.collections.Mapping
.References: #7291
Исправлена регрессия, при которой метод
CursorResult.fetchmany()
не приводил к автозакрытию курсора на стороне сервера (т.е. при использованииstream_results
илиyield_per
, ориентированных на Core или ORM), когда результаты были полностью исчерпаны.References: #7274
В будущих
Engine
исправлена проблема, когда вызовEngine.begin()
и вход в контекстный менеджер не закрывал соединение, если сама операция BEGIN по какой-то причине не выполнялась, например, обработчик события вызывал исключение; этот вариант использования не удалось протестировать для будущей версии движка. Обратите внимание, что «будущие» контекстные менеджеры, обрабатывающие блокиbegin()
в Core и ORM, не выполняют операцию «BEGIN» до тех пор, пока не будут введены контекстные менеджеры. Это отличается от старой версии, в которой операция «BEGIN» выполняется заранее.References: #7272
sql¶
В пространство имен импорта верхнего уровня
TupleType
добавленоsqlalchemy
.Исправлена ошибка, при которой объекты строк, возвращаемые в ORM-запросах, которые теперь являются обычными объектами
Row
, не интерпретировались операторомColumnOperators.in_()
как значения кортежей, которые должны быть разбиты на отдельные связанные параметры, и вместо этого передавались драйверу как одиночные значения, что приводило к сбоям. Изменение системы «расширения IN» теперь учитывает, что выражение уже имеет типTupleType
, и в этом случае значения обрабатываются соответствующим образом. В редких случаях использования «tuple-in» с нетипизированным выражением, например, текстовым выражением без информации о типе, значение кортежа определяется для значений, реализующихcollections.abc.Sequence
, но не являющихсяstr
илиbytes
, как всегда при проверке наSequence
.References: #7292
Исправлена проблема, при которой функция использования строковой метки для упорядочивания или группировки, описанная в Упорядочивание или группировка по метке, не работала корректно, если использовалась в конструкции
CTE
, когда CTE был встроен внутрь вложенного оператораSelect
, который сам был настроен как скалярный подзапрос.References: #7269
Исправлена ошибка, из-за которой конструкция
text()
больше не принималась в качестве целевого случая в списке «whens» внутри конструкцииcase()
. Регрессия, по-видимому, связана с попыткой защиты от некоторых форм литеральных значений, которые считались неоднозначными при передаче сюда; однако нет причин, по которым целевые случаи не должны интерпретироваться как открытые SQL-выражения, как и везде, и литеральная строка или кортеж будет преобразована в связанный параметр, как это было бы в других случаях.References: #7287
schema¶
Исправлена проблема в
Table
, когда при передаче параметра вместе сTable.extend_existing
для дополнения существующегоTable
параметрTable.implicit_returning
размещался некорректно.References: #7295
postgresql¶
Добавлены переопределяемые методы
PGDialect_asyncpg.setup_asyncpg_json_codec
иPGDialect_asyncpg.setup_asyncpg_jsonb_codec
codec, которые решают необходимую задачу регистрации кодеков JSON/JSONB для этих типов данных при использовании asyncpg. Изменения заключаются в том, что методы разбиты на отдельные переопределяемые методы для поддержки сторонних диалектов, которым необходимо изменить или отключить настройку этих кодеков.References: #7284
Изменен диалект asyncpg для привязки типа
Float
к типу «float» PostgreSQL вместо «numeric», чтобы можно было разместить значениеfloat(inf)
. Добавлена поддержка тестового набора для сохранения значения «inf».References: #7283
Улучшена работа с массивами при использовании PostgreSQL с диалектом pg8000.
References: #7167
mysql¶
Реорганизован список зарезервированных слов в два отдельных списка, один для MySQL, другой для MariaDB, для более точного управления этими расходящимися наборами слов; настроен диалект MySQL/MariaDB для переключения между этими списками в зависимости от явно настроенного или определяемого по версии сервера бэкенда «MySQL» или «MariaDB». Добавлены все текущие зарезервированные слова для MySQL 8 и текущих версий MariaDB, включая недавно добавленные ключевые слова типа «lead». Pull request любезно предоставлен Кевином Кирше (Kevin Kirsche).
References: #7167
Исправлена проблема в MySQL
Insert.on_duplicate_key_update()
, которая при использовании выражения в выражении VALUES приводила к неправильному отображению имени столбца. Pull request любезно предоставлен Кристианом Сабайлой.References: #7281
mssql¶
Внесены изменения в генерацию компилятором символов «после компиляции», включая символы, используемые для «расширения IN», а также для «карты перевода схемы», чтобы они не основывались непосредственно на строках, заключенных в скобки с символами подчеркивания, поскольку это напрямую противоречит формату цитирования SQL Server, также использующему скобки, что приводит к ложным совпадениям при замене компилятором символов «после компиляции» и «перевода схемы». Проблема создала легко воспроизводимые примеры как с методом
Inspector.get_schema_names()
при использовании его совместно с функциейConnection.execution_options.schema_translate_map
, так и в маловероятном случае, когда символ, совпадающий с внутренним именем «POSTCOMPILE», будет использоваться с функцией типа «expanding in».References: #7300
1.4.26¶
Released: October 19, 2021orm¶
Улучшено сообщение об исключении, выдаваемое при настройке отображения с наследованием объединенных таблиц, в которых либо не заданы отношения внешних ключей, либо заданы отношения нескольких внешних ключей. Теперь сообщение специфично для ORM и содержит контекст, указывающий на то, что параметр
Mapper.inherit_condition
может потребоваться, в частности, для случая неоднозначных внешних ключей.Исправлена проблема с функцией
with_loader_criteria()
, когда критерий ON не добавлялся в JOIN для запроса видаselect(A).join(B)
, указывающего цель при использовании неявного предложения ON.References: #7189
Исправлена ошибка, при которой «плагин» ORM, необходимый для корректной работы таких функций, как
with_loader_criteria()
, не применялся кselect()
, запрашиваемому из выражения ORM-столбца, если в нем использовался модификаторColumnElement.label()
.References: #7205
Добавить недостающие методы, добавленные в #6991, в
scoped_session
иasync_scoped_session()
.References: #7103
В функциональность
Query.join()
и ORM-версииSelect.join()
был добавлен дополнительный слой предупреждающих сообщений, в котором несколько мест, где продолжает происходить «автоматическое псевдонирование», теперь будут указываться как паттерн, которого следует избегать, в основном это относится к области наследования объединенных таблиц, где классы, имеющие общие базовые таблицы, объединяются без использования явных псевдонимов. В одном случае выдается предупреждение о том, что паттерн не рекомендуется использовать, в другом случае он полностью устарел.Автоматическое сглаживание в ORM join(), возникающее при пересечении сопоставленных таблиц, не работает согласованно со всеми API, такими как
contains_eager()
, и вместо того, чтобы продолжать пытаться заставить эти сценарии работать везде, замена на более явный для пользователя шаблон более понятна, менее подвержена ошибкам и еще больше упрощает внутреннее устройство SQLAlchemy.Предупреждения содержат ссылки на страницу errors.rst, на которой демонстрируется каждый паттерн, а также рекомендации по его исправлению.
Исправлена ошибка, при которой итерация
Result
изSession
после закрытияSession
приводила к частичному присоединению объектов к этой сессии в недопустимом состоянии. Теперь при итерации небуферизованного результата изSession
, который был закрыт или иным образом вызвал методSession.expunge_all()
после того, как был сгенерированResult
, возникает исключение со ссылкой на новую документацию. Опция выполненияprebuffer_rows
, автоматически используемая расширением asyncio для клиентских наборов результатов, может быть использована для полученияResult
, где объекты ORM предварительно буферизованы, и в этом случае итерация результата приведет к созданию серии отделенных объектов.References: #7128
В связи с #7153 исправлена проблема, при которой поиск столбцов результатов не выполнялся для «адаптированных» операторов SELECT, в которых выбирались выражения с «постоянными» значениями, чаще всего с выражением NULL, как это происходит в таких местах, как объединенная ускоренная загрузка в сочетании с limit/offset. В целом это была регрессия, связанная с выпуском #6259, который удалял все «адаптации» для констант типа NULL, «true» и «false» при переписывании выражений в SQL-операторе, но это нарушало ситуацию, когда та же логика адаптации использовалась для преобразования константы в маркированное выражение для целей таргетинга набора результатов.
References: #7154
Исправлена регрессия, в результате которой загруженные объекты ORM не могли быть замаринованы в случаях, когда опции загрузчика, использующие
"*"
, применялись в определенных комбинациях, например, при сочетании стратегии загрузчикаjoinedload()
сraiseload('*')
из подэлементов.References: #7134
Исправлена ошибка, при которой использование атрибута
hybrid_property
или сопоставленного атрибутаcomposite()
в качестве ключа, передаваемого в методUpdate.values()
для оператораUpdate
с поддержкой ORM, а также при использовании его через традиционный методQuery.update()
, обрабатывались на предмет входящих ORM/гибридных/композитных значений на этапе компиляции оператора UPDATE, что означало, что в тех случаях, когда происходило кэширование, последующие вызовы этого же оператора уже не получали корректных значений. Это относится не только к гибридам, использующим методhybrid_property.update_expression()
, но и к любому использованию простого гибридного атрибута. Для композитов эта проблема приводила к генерации неповторяющегося ключа кэша, что нарушало кэширование и могло заполнить кэш утверждений повторяющимися утверждениями.Теперь конструкция
Update
обрабатывает пары ключ/значение, передаваемые вUpdate.values()
иUpdate.ordered_values()
, заранее, когда конструкция генерируется впервые, до того, как будет сгенерирован ключ кэша, чтобы пары ключ/значение обрабатывались каждый раз, и чтобы ключ кэша генерировался по отдельным парам столбец/значение, которые в конечном итоге будут использоваться в операторе.References: #7209
Передача объекта
Query
вSession.execute()
не является использованием этого объекта по назначению, и теперь будет выдано предупреждение об устаревании.References: #6284
examples¶
Исправлены примеры в examples/versioned_rows для корректного использования API SQLAlchemy 1.4; эти примеры были упущены при внесении изменений в API, таких как удаление «passive» из
Session.is_modified()
, а также добавление крючка событийSessionEvents.do_orm_execute()
.References: #7169
engine¶
Исправлена проблема, при которой предупреждение об устаревании конструктора
URL
, указывающее на необходимость использования методаURL.create()
, не выдавалось, если передавался полный позиционный список аргументов из семи аргументов; кроме того, при таком вызове конструктора теперь будет выполняться проверка аргументов URL, которая ранее пропускалась.References: #7130
Метод
Inspector.reflect_table()
теперь поддерживает отражение таблиц, не имеющих определенных пользователем столбцов. Это позволяетMetaData.reflect()
корректно завершать отражение на базах данных, содержащих такие таблицы. В настоящее время из распространенных бэкендов баз данных такая конструкция поддерживается только в PostgreSQL.References: #3247
Реализованы соответствующие методы
__reduce__()
для всех объектов исключений SQLAlchemy, чтобы гарантировать, что все они поддерживают чистые обходы при травлении, так как объекты исключений часто сериализуются для целей различных отладочных инструментов.References: #7077
sql¶
Исправлена проблема, при которой SQL-запросы, использующие конструкцию
FunctionElement.within_group()
, не могли быть травлеными, как правило, при использовании расширенияsqlalchemy.ext.serializer
, а также при общем травлении.References: #6520
Исправлена проблема в новом параметре
HasCTE.cte.nesting
, введенном в #4123, когда рекурсивныйCTE
, использующийHasCTE.cte.recursive
в типичной связке с UNION, компилировался некорректно. Дополнительно внесены некоторые коррективы, чтобы конструкцияCTE
создавала корректный ключ кэша. Pull request любезно предоставлен Эриком Массераном.References: #4123
Учет параметра
table.schema
, переданного в конструкциюtable()
, таким образом, чтобы он учитывался при обращении к атрибутуTableClause.fullname
.References: #7061
Исправлено несоответствие в функциях/методах
ColumnOperators.any_()
/ColumnOperators.all_()
, когда специальное поведение этих функций, заключающееся в «переворачивании» выражения таким образом, что выражение «ANY» / «ALL» всегда находится справа, не работало, если сравнение производилось со значением None, то есть «column.any_() == None» должно давать то же SQL-выражение, что и «null() == column.any_()». Добавлена дополнительная документация, уточняющая этот момент, а также упоминание о том, что any_() / all_() в общем случае заменяет ARRAY-версию «any()» / «all()».References: #7140
Исправлена проблема, при которой «расширение IN» некорректно работало с типами данных, использующими метод
TypeEngine.bind_expression()
, когда метод необходимо было применять к каждому элементу выражения IN, а не ко всему выражению IN.References: #7177
Внесены изменения в новую для 1.4 логику «разотождествления столбцов», когда одно и то же выражение при повторении получает метку «extra anonymous», с тем чтобы логика более агрессивно дедуплицировала эти метки, когда повторяющийся элемент каждый раз является одним и тем же объектом выражения Python, как это происходит в случаях использования значений «singleton» типа
null()
. Это основано на наблюдении, что, по крайней мере, некоторые базы данных (например, MySQL, но не SQLite) выдают ошибку, если одна и та же метка повторяется внутри подзапроса.References: #7153
mypy¶
Исправлена проблема в плагине mypy для устранения некоторых проблем с обнаружением
Enum()
SQL-типов, содержащих пользовательские классы перечислений Python. Pull request любезно предоставлен Хироши Огавой.References: #6435
postgresql¶
Добавлено условие «отключения» для сообщения об ошибке «Ошибка SSL SYSCALL: Bad address», о чем сообщил psycopg2. Pull request любезно предоставлен Зиком Брехтелем (Zeke Brechtel).
References: #5387
Исправлена проблема, когда IN-выражения по отношению к серии элементов массива, как это можно сделать в PostgreSQL, не работали корректно из-за многочисленных проблем в функции «расширяющего IN» SQLAlchemy Core, которая была стандартизирована в версии 1.4. Диалект psycopg2 теперь использует метод
TypeEngine.bind_expression()
сARRAY
для переносимого применения корректных приведений к элементам. Диалект asyncpg не был затронут этой проблемой, так как он применяет приведения на уровне биндов на уровне драйвера, а не на уровне компилятора.References: #7177
mysql¶
Исправления, связанные с переходом на серию MariaDB 10.6, включают несовместимые с предыдущими версиями изменения как в Python-драйвере mariadb-connector (поддерживается только в SQLAlchemy 1.4), так и в собственных клиентских библиотеках 10.6, которые автоматически используются DBAPI mysqlclient (применимо как к 1.3, так и к 1.4). Символ кодировки «utf8mb3» теперь сообщается этими клиентскими библиотеками, когда кодировка указана как «utf8», что приводит к ошибкам поиска и кодировки в диалекте MySQL, который не ожидает этого символа. Обновлены как базовая библиотека MySQL для учета этого символа utf8mb3, так и тестовый набор. Спасибо Георгу Рихтеру за поддержку.
This change is also backported to: 1.3.25
Исправлена проблема в конструкции MySQL
match()
, когда передача выражения клаузы, напримерbindparam()
, или другого SQL-выражения для параметра «against» приводила к ошибке. Pull request любезно предоставлен Антоном Ковалевичем.References: #7144
Исправлена проблема установки, при которой модуль
sqlalchemy.dialects.mysql
не импортировался, если не был установлен «greenlet».References: #7204
mssql¶
Добавлена поддержка отражения опций внешних ключей SQL Server, включая «ON UPDATE» и «ON DELETE», значения «CASCADE» и «SET NULL».
Исправлена проблема с
Inspector.get_foreign_keys()
, когда внешние ключи опускались, если они были установлены по уникальному индексу, а не по уникальному ограничению.References: #7160
Исправлена ошибка
Inspector.has_table()
, когда при запросе к tempdb локальная временная таблица с таким же именем из другой сессии возвращала False. Это продолжение #6910, которое учитывало, что временная таблица существует только в альтернативной сессии, а не в текущей.References: #7168
Исправлена ошибка в типе данных SQL Server
DATETIMEOFFSET
, когда реализация ODBC не генерировала корректный DDL для случаев, когда тип был преобразован методомdialect.type_descriptor()
, использование которого показано в некоторых документированных примерах дляTypeDecorator
, хотя и не является необходимым для большинства типов данных. Регрессия была введена в #6366. В рамках этого изменения полный список типов дат SQL Server был изменен, чтобы возвращать «dialect impl», который генерирует то же самое имя DDL, что и супертип.References: #7129
1.4.25¶
Released: September 22, 2021platform¶
Исправлена регрессия, связанная с #7024, когда при реорганизации имен «platform machine», используемых зависимостью
greenlet
, неправильно писалось «aarch64» и дополнительно опускался верхний регистр «AMD64», что необходимо для Windows-машин. Pull request любезно предоставлен Джеймсом Доу.References: #7024
1.4.24¶
Released: September 22, 2021platform¶
В дальнейшем спецификатор пакета «greenlet» в файле setup.cfg был скорректирован таким образом, чтобы при сравнении
platform_machine
с конкретным идентификатором использовалась длинная цепочка выражений «или», в результате чего совпадала только полная строка.References: #7024
orm¶
Добавлены опции загрузчика к
Session.merge()
иAsyncSession.merge()
через новый параметрSession.merge.options
, который будет применять заданные опции загрузчика кget()
, используемому внутри процесса слияния, что позволяет применять ускоренную загрузку отношений и т.д., когда процесс слияния загружает новый объект. Pull request любезно предоставлен Дэниелом Стоуном.References: #6955
Исправлена проблема ORM, когда выражения столбцов, передаваемые в
query()
или в ORM-выражениеselect()
, дедуплицировались на идентичность объекта, например, фразаselect(A.id, null(), null())
выдавала только одно выражение «NULL», что ранее в 1.3 было не так. Однако это изменение также позволяет ORM-выражениям отображаться как заданные, например, фразаselect(A.data, A.data)
будет выдавать строку результатов с двумя столбцами.References: #6979
Исправлена проблема в недавно исправленном методе
Query.with_entities()
, когда флаг, определяющий автоматическую уникальность только для старых объектов ORMQuery
, устанавливался в значениеTrue
в случаях, когда вызовwith_entities()
устанавливалQuery
для возврата строк только с колонками, которые не являются уникальными.References: #6924
engine¶
Улучшить интерфейс, используемый адаптированными драйверами, например, asyncio, для доступа к реальному объекту соединения, возвращаемому драйвером.
Объект
_ConnectionFairy
имеет два новых атрибута:_ConnectionFairy.dbapi_connection
всегда представляет собой объект, совместимый с DBAPI. Для драйверов pep-249 это соединение DBAPI в том виде, в котором оно всегда было, ранее доступ к нему осуществлялся по атрибуту.connection
. Для драйверов asyncio, которые SQLAlchemy адаптирует к интерфейсу pep-249, возвращаемый объект обычно будет объектом адаптации SQLAlchemy с именемAdaptedConnection
._ConnectionFairy.driver_connection
всегда представляет собой реальный объект соединения, поддерживаемый сторонним pep-249 DBAPI или используемым async-драйвером. Для стандартных pep-249 DBAPI это всегда будет тот же объект, что и вdbapi_connection
. Для асинхронного драйвера это будет базовый объект соединения, поддерживающий только асинхронный режим.
Атрибут
.connection
остается доступным и теперь является унаследованным псевдонимом.dbapi_connection
.References: #6832
Добавлены новые методы
Session.scalars()
,Connection.scalars()
,AsyncSession.scalars()
иAsyncSession.stream_scalars()
, обеспечивающие сокращение сценария получения рядоориентированного объектаResult
и преобразования его в объектScalarResult
с помощью методаResult.scalars()
для возврата списка значений, а не списка строк. Новые методы аналогичны давно существующим методамSession.scalar()
иConnection.scalar()
, используемым для возврата единственного значения только из первой строки. Pull request любезно предоставлен Мигелем Гринбергом.References: #6990
Исправлена проблема, в результате которой была случайно удалена возможность метода
ConnectionEvents.before_execute()
изменять переданный объект SQL-оператора, возвращая новый объект для вызова. Это поведение было восстановлено.References: #6913
Убедитесь, что
str()
вызывается по аргументу anURL.create.password
, что позволяет использовать в качестве атрибутов пароля объекты, реализующие метод__str__()
. Также уточнено, что один такой объект не подходит для динамической смены пароля для каждого соединения с базой данных; вместо него следует использовать подходы в Генерация динамических маркеров аутентификации.References: #6958
Исправлена проблема в
URL
, когда проверка значения «drivername» неадекватно реагировала на значениеNone
, где ожидалась строка.References: #6983
Исправлена проблема, при которой движок с флагом
create_engine.implicit_returning
, установленным в False, не работал при использовании функции PostgreSQL «fast insertmany» в сочетании с флагомSequence
, а также при использовании любого типа «executemany» с «return_defaults()» в сочетании с флагомSequence
. Заметим, что «быстрый insertmany» PostgreSQL использует «RETURNING» по определению, когда SQL-оператор передается драйверу; в целом, флагcreate_engine.implicit_returning
является унаследованным и не имеет реального применения в современной SQLAlchemy, и будет устаревшим в отдельном изменении.References: #6963
sql¶
В конструктор
CTE
и методHasCTE.cte()
добавлен новый параметрHasCTE.cte.nesting
, который помечает CTE как такой, который должен оставаться вложенным в окружающий CTE, а не перемещаться на верхний уровень крайнего SELECT. Хотя в подавляющем большинстве случаев разницы в функциональности SQL не наблюдается, пользователи выявили различные крайние случаи, когда истинная вложенность конструкций CTE является желательной. Большое спасибо Эрику Массерану за большую работу над этой сложной функцией.References: #4123
Реализованы отсутствующие методы в
FunctionElement
, которые, будучи неиспользуемыми, приводили к тому, что pylint сообщал о них как о нереализованных абстрактных методах.References: #7052
Исправлены две проблемы, когда комбинации
select()
иjoin()
при адаптации для формирования копии элемента не полностью копировали состояние всех объектов столбцов, связанных с подзапросами. Основная проблема, которую это вызывало, заключалась в том, что при использовании методаClauseElement.params()
(который, вероятно, следует перевести в категорию legacy, поскольку он неэффективен и чреват ошибками) оставались копии старых объектовBindParameter
, что приводило к проблемам с правильной установкой параметров во время выполнения.References: #7055
Исправлена проблема, связанная с новой функцией
HasCTE.add_cte()
, когда при одновременном сопряжении двух операторов «INSERT…FROM SELECT» терялась связь между двумя независимыми операторами SELECT, что приводило к неправильному SQL.References: #7036
Исправлена проблема, при которой использование выражений столбцов ORM в качестве ключей в списке словарей, передаваемых в
Insert.values()
для «многозначной вставки», не обрабатывалось корректно в правильные выражения столбцов.References: #7060
mypy¶
Исправлена проблема, при которой плагин mypy аварийно завершал работу при интерпретации конструкции
query_expression()
.References: #6950
Исправлена проблема в плагине mypy, когда столбцы на mixin не интерпретировались корректно, если отображаемый класс полагался на процедуру
__tablename__
, пришедшую из суперкласса.References: #6937
asyncio¶
Добавлена начальная поддержка драйвера базы данных
asyncmy
asyncio для MySQL и MariaDB. Этот драйвер очень новый, но, похоже, является единственной альтернативой драйверуaiomysql
, который в настоящее время не поддерживается и не работает с текущими версиями Python. Большое спасибо long2ice за pull request на этот диалект.См.также
References: #6993
Теперь
AsyncSession
поддерживает переопределение того, какойSession
используется в качестве проксируемого экземпляра. Пользовательский классSession
может быть передан с помощью параметраAsyncSession.sync_session_class
или путем подклассификацииAsyncSession
и указания пользовательскогоAsyncSession.sync_session_class
.References: #6746
Исправлена ошибка в
AsyncSession.execute()
иAsyncSession.stream()
, из-за которойexecution_options
при определении должен был быть экземпляромimmutabledict
. Теперь он корректно принимает любое отображение.References: #6943
Добавлены недостающие аргументы
**kw
в методAsyncSession.connection()
.Отказаться от использования
scoped_session
с драйверами asyncio. При использовании Asyncio вместо него следует использоватьasync_scoped_session
.References: #6746
postgresql¶
Квалифицируйте вызов
version()
, чтобы избежать проблем с «тенью», если пользователем настроен другой путь поиска.References: #6912
Тип данных
ENUM
является нативным для PostgreSQL и поэтому не должен использоваться с флагомnative_enum=False
. Теперь этот флаг игнорируется при передаче типу данныхENUM
и выдается предупреждение; ранее этот флаг приводил к некорректной работе объекта типа.References: #6106
sqlite¶
Исправлена ошибка, при которой в сообщении об ошибке SQLite invalid isolation level на драйвере pysqlite не указывалось, что «AUTOCOMMIT» является одним из допустимых уровней изоляции.
mssql¶
Исправлена проблема, при которой
sqlalchemy.engine.reflection.has_table()
возвращало значениеTrue
для локальных временных таблиц, которые на самом деле принадлежали другому сеансу (соединению) SQL Server. Теперь выполняется дополнительная проверка, чтобы убедиться, что обнаруженная временная таблица действительно принадлежит текущему сеансу.References: #6910
oracle¶
Добавлен CAST(VARCHAR2(128)) к параметрам «имя таблицы», «владелец» и другим DDL-именам, используемым в рефлексивных запросах к системным представлениям Oracle, таким как ALL_TABLES, ALL_TAB_CONSTRAINTS и т.п., для улучшения возможности индексации по этим столбцам, поскольку ранее они неявно обрабатывались как NVARCHAR2 из-за использования в Python Unicode для строк; эти столбцы документированы во всех версиях Oracle как VARCHAR2 с длиной от 30 до 128 символов в зависимости от версии сервера. Кроме того, включена поддержка тестирования DDL-структур с Unicode-именами в базах данных Oracle.
References: #4486
1.4.23¶
Released: August 18, 2021general¶
Требования к установке были изменены таким образом, что
greenlet
является требованием по умолчанию только для тех платформ, для которых хорошо известна возможность установкиgreenlet
и для которых уже есть предварительно собранный бинарник на pypi; текущий список -x86_64 aarch64 ppc64le amd64 win32
. Для других платформ greenlet по умолчанию не устанавливается, что должно позволить установить и запустить тестовый набор SQLAlchemy 1.4 на платформах, не поддерживающихgreenlet
, исключая любые возможности asyncio. Для установки с включенной зависимостьюgreenlet
на архитектуру машины, не входящую в приведенный выше список, можно включить дополнительную зависимость[asyncio]
, выполнив командуpip install sqlalchemy[asyncio]
, которая затем попытается установитьgreenlet
.Кроме того, тестовый набор был исправлен таким образом, чтобы тесты могли полностью завершаться, когда greenlet не установлен, с соответствующими пропусками для тестов, связанных с асинхронностью.
References: #6136
orm¶
Добавлен новый атрибут
Select.columns_clause_froms
, который будет получать список FROM, подразумеваемый предложением columns оператораSelect
. От старой коллекцииSelect.froms
она отличается тем, что не выполняет никаких шагов компиляции ORM, которые обязательно деаннотируют элементы FROM и делают такие вещи, как вычисление объединенных нагрузок и т.д., что делает ее неподходящим кандидатом для методаSelect.select_from()
. Дополнительно добавляется новый параметрSelect.with_only_columns.maintain_column_froms
, который передает эту коллекцию вSelect.select_from()
перед заменой коллекции столбцов.Кроме того,
Select.froms
переименован вSelect.get_final_froms()
, чтобы подчеркнуть, что эта коллекция не является простым аксессором, а вычисляется с учетом полного состояния объекта, что может быть дорогостоящим вызовом при использовании в контексте ORM.Дополнительно исправлена регрессия, связанная с функцией
with_only_columns()
для поддержки применения критериев к элементам колонок, которые были заменены наSelect.with_only_columns()
илиQuery.with_entities()
, которая была сломана в #6503, выпущенной в версии 1.4.19.References: #6808
Исправлена проблема, когда «клонированный» объект связанного параметра приводил к конфликту имен в компиляторе, если в одном операторе одновременно использовалось более одного клона этого параметра. В частности, это могло происходить в таких случаях, как ORM-запросы с наследованием одной таблицы, в которых одно и то же значение «дискриминатора» указывалось несколько раз в одном запросе.
References: #6824
Исправлена проблема в стратегиях загрузчика, когда использование метода
Load.options()
, особенно при вложении нескольких вызовов, генерировало слишком длинный и, что более важно, недетерминированный ключ кэша, что приводило к очень большим ключам кэша, которые также не позволяли эффективно использовать кэш, как с точки зрения общего объема используемой памяти, так и количества записей, используемых в самом кэше.References: #6869
Пересмотрены средства, с помощью которых аксессор
ORMExecuteState.user_defined_options
получаетUserDefinedOption
и связанные с ним объекты опций из контекста, причем особое внимание уделено стратегии «selectinload» на загрузчике, где ранее это не работало; в других стратегиях такой проблемы не было. Объекты, связанные с текущим выполняемым запросом, а не с запросом, находящимся в кэше, теперь распространяются безусловно. Это позволяет отделить их от опций «стратегии загрузчика», которые явно связаны с состоянием скомпилированного запроса и должны использоваться по отношению к кэшируемому запросу.В результате этого исправления пользовательская опция, например, используемая в примере dogpile.caching, а также в других рецептах, таких как определение «идентификатора шарда» для расширения горизонтального разделения, будет корректно передаваться в eager и lazy loaders независимо от того, был ли в конечном итоге вызван кэшированный запрос.
References: #6887
Исправлена проблема, при которой единица работы внутренне использовала устаревшую до 2.0 форму выражения SQL, выдавая предупреждение об устаревании, если была включена функция SQLALCHEMY_WARN_20.
References: #6812
Исправлена проблема в
selectinload()
, когда при использовании новой функцииPropComparator.and_()
внутри опций, вложенных более чем на один уровень, не обновлялись значения связанных параметров, которые находились во вложенных критериях, что являлось побочным эффектом кэширования SQL-операторов.References: #6881
Скорректированы внутренние компоненты ORM-загрузчика, которые больше не используют систему «лямбда-кэширования», добавленную в 1.4, а также исправлено одно место, в котором для запроса по-прежнему использовалась прежняя система «запеченных запросов». Система лямбда-кэширования остается эффективным способом снижения затрат на создание запросов, имеющих относительно постоянный характер использования. В случае стратегий загрузчиков используемые запросы отвечают за перемещение по множеству произвольных опций и критериев, которые как генерируются, так и иногда потребляются кодом конечного пользователя, что делает концепцию лямбда-кэширования не более эффективной, чем ее отказ от использования, ценой большей сложности. В частности, проблемы, отмеченные #6881 и #6887, существенно снижаются при внутреннем удалении этой возможности.
Исправлена проблема, при которой конструкция
Bundle
не создавала правильных ключей кэша, что приводило к неэффективному использованию кэша запросов. Это оказывало некоторое влияние на стратегию «selectinload» и было выявлено в рамках #6889.References: #6889
sql¶
Исправление проблемы в
CTE
, когда новый методHasCTE.add_cte()
, добавленный в версии 1.4.21 / #6752, не работал корректно для структур «compound select», таких какunion()
,union_all()
,except()
и т.д. Pull request любезно предоставлен Эриком Массераном.References: #6752
Исправлена проблема в методе
CacheKey.to_offline_string()
, используемом в примере dogpile.caching, когда при попытке создать правильный ключ кэша из специального «лямбда»-запроса, генерируемого ленивым загрузчиком, значения параметров не учитывались, что приводило к некорректному ключу кэша.References: #6858
Настроена функция предупреждения «from linter» для работы с цепочкой джойнов глубиной более одного уровня, в которой клаузулы ON не имеют явного соответствия целей, например, выражение типа «ON TRUE». Этот способ использования предназначен для отмены предупреждения о картезианском произведении просто за счет того, что существует JOIN from «a to b», что не работало для случая, когда цепочка соединений имела более одного элемента.
References: #6886
Исправлена проблема в системе лямбда-кэширования, когда элемент запроса, не содержащий ключа кэша, например, элемент пользовательской опции или клаузулы, все равно неадекватно заполнял выражение в «лямбда-кэше».
schema¶
Унифицировать поведение
Enum
в родной и неродной реализациях относительно принимаемых значений для перечисления с псевдонимами. КогдаEnum.omit_aliases
равноFalse
, все значения, включая псевдонимы, принимаются как допустимые. КогдаEnum.omit_aliases
имеет значениеTrue
, в качестве допустимых значений принимаются только не алиасные значения.References: #6146
mypy¶
Добавлена поддержка определения классов SQLAlchemy в пользовательском коде с использованием синтаксиса «generic class», как это определено в
sqlalchemy2-stubs
, напримерColumn[String]
, без необходимости квалификации этих конструкций в блокеTYPE_CHECKING
путем реализации специального метода Python__class_getitem__()
, который позволяет этому синтаксису проходить без ошибок во время выполнения.
postgresql¶
В операторы PostgreSQL «overlaps», «contained_by», «contains» добавлен флаг «is_comparison», чтобы они работали в соответствующих контекстах ORM, а также в связке с функцией «from linter».
References: #6886
mssql¶
Исправлена проблема, при которой флаг компилятора
literal_binds
, используемый для вывода связанных параметров в строку, не работал при использовании определенного класса параметров, известного как «literal_execute», который охватывает такие параметры, как LIMIT и OFFSET для диалектов, где драйверы не позволяют использовать связанные параметры, например, клаузу «TOP» в SQL Server. Локально проблема, похоже, затрагивает только диалект MSSQL.References: #6863
misc¶
Исправлена проблема, при которой расширение горизонтального шардинга некорректно учитывало обычный текстовый SQL-оператор, переданный в
Session.execute()
.References: #6816
1.4.22¶
Released: July 21, 2021orm¶
Исправлена проблема в новом методе
Table.table_valued()
, когда результирующая конструкцияTableValuedColumn
некорректно реагировала на адаптацию псевдонимов, используемую в ORM, например, для eager loading, polymorphic loading и т.д.References: #6775
Исправлена проблема, при которой использование метода
Result.unique()
с результатом ORM, включающим столбцовые выражения с нехешируемыми типами, такими какJSON
илиARRAY
, использующими не кортежи, приводило к тихому откату к использованию функцииid()
, а не к возникновению ошибки. Теперь при использовании методаResult.unique()
в ORM-запросе в стиле 2.0 выдается ошибка. Кроме того, хешируемость принимается за True для значений результатов неизвестного типа, как это часто бывает при использовании SQL-функций с неизвестным возвращаемым типом; если значения действительно не являются хешируемыми, то сама функцияhash()
будет вызывать ошибку.Для старых ORM-запросов, поскольку старый объект
Query
уникализируется во всех случаях, сохраняются старые правила, согласно которым для значений результатов неизвестного типа следует использоватьid()
, поскольку эта старая уникализация в основном предназначена для уникализации ORM-сущностей, а не значений столбцов.References: #6769
Исправлена проблема, при которой очистка мапперов во время таких операций, как завершение работы тестового набора, могла вызвать предупреждение «размер словаря изменился» во время сборки мусора из-за итерации словаря со слабыми ссылками. Для предотвращения влияния параллельной GC на эту операцию был применен флажок
list()
.References: #6771
Исправлена критическая проблема с кэшированием, когда функция сохранения в ORM с помощью INSERT..RETURNING кэшировала некорректный запрос при смешивании форм INSERT «bulk save» и стандартной «flush».
References: #6793
engine¶
В систему событий добавлены некоторые защиты от
KeyError
, чтобы учесть случай, когда интерпретатор завершается одновременно с вызовомEngine.dispose()
, что привело бы к появлению предупреждений о трассировке стека.References: #6740
sql¶
Исправлена проблема, при которой использование параметра
case.whens
при передаче словаря позиционно, а не в качестве аргумента ключевого слова, выдавало предупреждение об устаревании версии 2.0, ссылаясь на устаревание передачи списка позиционно. Формат словаря «whens», передаваемый позиционно, по-прежнему поддерживается и случайно был помечен как устаревший.References: #6786
Исправлена проблема, при которой обработчики связанных параметров не вызывались в случае использования метода
Insert.values()
со значением PythonNone
; в частности, это было заметно при использовании типа данныхJSON
, а также связанных с ним типов PostgreSQL, таких какJSONB
, которые не могли закодировать значение PythonNone
в JSON null, однако проблема была обобщена на любой обработчик связанных параметров в сочетании с этим специфическим методомInsert
.References: #6770
1.4.21¶
Released: July 14, 2021orm¶
Изменен подход к отслеживанию истории отношений скалярных объектов, которые не являются отношениями «многие-к-одному», т.е. отношений «один-к-одному», которые в противном случае были бы отношениями «один-ко-многим». При замене значения «один к одному» заменяемое «старое» значение больше не загружается сразу, а обрабатывается в процессе промывки. Это устраняет исторически возникшую проблему «ленивой» загрузки, которая в противном случае часто возникает при присваивании атрибуту «один к одному», и особенно часто возникает при использовании «lazy=“raise“», а также в случаях использования asyncio.
Это изменение приводит к изменению поведения события
AttributeEvents.set()
, которое, тем не менее, в настоящее время не документировано. Оно заключается в том, что событие, примененное к такому атрибуту «один к одному», больше не будет получать «старый» параметр, если оно выгружено и флагrelationship.active_history
не установлен. Как указано вAttributeEvents.set()
, если обработчику события необходимо получать «старое» значение при срабатывании события, то флаг active_history должен быть установлен либо у слушателя события, либо у отношения. Подобное поведение уже характерно для других видов атрибутов, таких как ссылки «многие-к-одному» и ссылки на значения столбцов.Это изменение дополнительно откладывает обновление обратной ссылки на «старое» значение в менее распространенном случае, когда «старое» значение локально присутствует в сессии, но не загружено в рассматриваемое отношение, до следующей промывки. Если это вызывает проблему, то опять же обычный флаг
relationship.active_history
может быть установлен наTrue
для отношения.References: #6708
Исправлена регрессия, возникшая в 1.4.19 из-за #6503 и связанная с
Query.with_entities()
, когда при использовании операций над множествами, таких какQuery.union()
, новая используемая структура неправомерно передавалась во вложенныйQuery
, в результате чего инструкции JOIN внутри применялись и к внешнему запросу.References: #6698
Исправлена регрессия, возникшая в версии 1.4.3 из-за #6060, когда правила, ограничивающие ORM-адаптацию производных selectables, мешали другим случаям ORM-адаптации, в частности, при применении адаптации для
with_polymorphic()
к отображению, использующемуcolumn_property()
, которое, в свою очередь, использует скалярный select, включающийaliased()
объект отображаемой таблицы.References: #6762
Исправлена ошибка ORM, при которой имена специальных меток, генерируемые для гибридных свойств и, возможно, других подобных типов выражений с поддержкой ORM, обычно распространялись наружу через подзапросы, что позволяло сохранять имя в конечных ключах результирующего набора даже при выборе из подзапросов. В этом случае отслеживается дополнительное состояние, которое не теряется при выборе гибрида из Core select / подзапроса.
References: #6718
sql¶
Добавлен новый метод
HasCTE.add_cte()
к каждой из конструкцийselect()
,insert()
,update()
иdelete()
. Этот метод добавит данныйCTE
в качестве «независимого» CTE оператора, то есть он будет отображаться в клаузу WITH над оператором безоговорочно, даже если на него нет других ссылок в первичном операторе. Это популярный случай использования в базе данных PostgreSQL, когда CTE используется для оператора DML, который работает со строками базы данных независимо от основного оператора.References: #6752
Исправлена проблема в конструкциях CTE, когда рекурсивный CTE, ссылающийся на SELECT с дублирующимися именами столбцов, которые обычно дедуплицируются с помощью логики маркировки в 1.4, не мог корректно ссылаться на дедуплицированное имя метки в предложении WITH.
References: #6710
Исправлена ошибка, при которой конструкция
tablesample()
не выполнялась, если она была построена для значения выборки с плавающей точкой, не встроенного в функцию SQL.References: #6735
postgresql¶
Исправлена проблема в
Insert.on_conflict_do_nothing()
иInsert.on_conflict_do_update()
, когда имя уникального ограничения, переданное в качестве параметраconstraint
, не обрезалось по длине, если оно было основано на соглашении об именовании, которое генерировало слишком длинное имя для максимальной длины идентификатора PostgreSQL, равной 63 символам, аналогично тому, как это происходит в операторе CREATE TABLE.References: #6755
Исправлена проблема, при которой тип данных PostgreSQL
ENUM
, встроенный в тип данныхARRAY
, не срабатывал корректно при создании/выгрузке, если использовалась функцияschema_translate_map
. Кроме того, была устранена связанная с этим проблема, когда та же самая функцияschema_translate_map
не работала для типа данныхENUM
в комбинации сCAST
, что также связано с тем, как комбинацияARRAY(ENUM)
работает в диалекте PostgreSQL.References: #6739
Исправлена проблема в
Insert.on_conflict_do_nothing()
иInsert.on_conflict_do_update()
, когда имя уникального ограничения, передаваемое в качестве параметраconstraint
, не заключалось в кавычки, если содержало символы, требующие кавычек.References: #6696
mssql¶
Исправлена ошибка, при которой специальная обработка точечных имен схем для диалекта SQL Server работала некорректно, если точечное имя схемы использовалось в функции
schema_translate_map
.References: #6697
1.4.20¶
Released: June 28, 2021orm¶
Исправлена ошибка в ORM, связанная с внутренним шагом восстановления конструкции
with_polymorphic()
, когда при обработке запроса происходит сборка мусора в пользовательском объекте. При восстановлении не обеспечивалась обработка подсубъектов для «полиморфного» случая, что приводило к появлению конструкцииAttributeError
.References: #6680
Скорректированы операции
Query.union()
и аналогичные операции с множествами для корректной совместимости с новыми возможностями, только что добавленными в #6661, с SQLAlchemy 1.4. 19, в результате чего операторы SELECT, отображаемые как элементы UNION или другой операции набора, будут включать непосредственно отображаемые столбцы, которые отображаются как отложенные; это устраняет регрессию, связанную с объединениями с несколькими уровнями вложенности, которая приводила к несоответствию столбцов, а также позволяет использовать опциюundefer()
на верхнем уровне такогоQuery
без необходимости применять опцию к каждому из элементов внутри UNION.References: #6678
Скорректирована проверка в маппере на вызываемый объект, который используется в качестве функции валидатора
@validates
или функции реконструкции@reconstructor
, чтобы проверка на «вызываемость» была более свободной, например, для объектов, основанных на фундаментальных атрибутах__func__
и__call__
, а не для проверки наMethodType
/FunctionType
, что позволяет таким вещам, как функции cython, работать правильно. Pull request любезно предоставлен Miłosz Stypiński.References: #6538
engine¶
Исправлена проблема в расширении C для класса
Row
, которая могла привести к утечке памяти в маловероятном случае, когда объектRow
ссылался на объект ORM, который затем мутировал для обратного обращения к самомуRow
, создавая цикл. Для этого случая в родную реализациюRow
был добавлен API Python C для отслеживания циклов GC.References: #5348
Исправлена старая проблема, когда при выполнении операции
select()
против лексемы «*», которая затем давала ровно один столбец, не удавалось правильно организовать имя столбцаcursor.description
в ключах объекта result.References: #6665
sql¶
Добавить в конструктор
PickleType
параметр impl, позволяющий использовать любой произвольный тип вместо стандартной реализацииLargeBinary
. Pull request courtesy jason3gb.References: #6646
Исправлена иерархия классов для базы
Sequence
и более общей базыDefaultGenerator
, поскольку они являются «исполняемыми» в виде операторов, то должны включать в свою иерархиюExecutable
, а не толькоStatementRole
, как это произвольно делалось ранее дляSequence
. Исправление позволяетSequence
работать во всех методах.execute()
, в том числе и сSession.execute()
, который не работал в случае, когда также был создан обработчикSessionEvents.do_orm_execute()
.References: #6668
schema¶
Исправлена проблема, при которой передача
None
для значенияTable.prefixes
приводила к сохранению не пустого списка, а константыNone
, что могло быть неожиданным для сторонних диалектов. Проблема выявлена при использовании в последних версиях Alembic, которые передаютNone
для этого значения. Pull request любезно предоставлен Каем Мюллером.References: #6685
mysql¶
Внесена небольшая корректировка в функцию отражения таблиц в диалекте MySQL для адаптации к альтернативным базам данных, ориентированным на MySQL, таким как TiDB, которые включают свои собственные директивы «комментарий» в конце директивы ограничения в «CREATE TABLE», где формат не содержит дополнительного символа пробела после комментария, в данном случае это функция TiDB «кластеризованный индекс». Pull request любезно предоставлен Daniël van Eeden.
References: #6659
misc¶
Исправлена ошибка в расширении
sqlalchemy.ext.automap
, в результате которой при создании явного сопоставленного класса с таблицей, которая также являетсяrelationship.secondary
элементомrelationship()
, генерируемого automap, выдавалось предупреждение «overlaps», введенное в 1.4 и обсуждаемое в отношение X скопирует столбец Q в столбец P, что противоречит отношению(ям): „Y“. Хотя при генерации этого случая из automap сохраняются те же предостережения, что и в случае с предупреждением «перекрытия», поскольку automap предназначен для более специальных случаев использования, условие, вызывающее предупреждение, отключается при генерации отношения «многие-ко-многим» с этим конкретным шаблоном.References: #6679
1.4.19¶
Released: June 22, 2021orm¶
Исправлены дальнейшие регрессии в той же области, что и в #6052, когда опции загрузчика, а также вызовы методов типа
Query.join()
при замене левой части оператора, от которого зависит опция/соединение, на методQuery.with_entities()
или при использовании запросов в стиле 2.0 на методSelect.with_only_columns()
приводили к ошибке. К объектам добавлен новый набор состояний, отслеживающий «левые» сущности, по отношению к которым были сделаны опции/соединения, который запоминается при изменении ведущих сущностей.Доработано поведение рендеринга подзапросов ORM в отношении отложенных столбцов и свойств столбцов с целью повышения совместимости с 1.3, а также с учетом новых возможностей 1.4. Поскольку в подзапросе 1.4 не используются опции загрузчика, включая
undefer()
, в подзапросе к ORM-сущности с отложенными атрибутами теперь будут отображаться те отложенные атрибуты, которые ссылаются непосредственно на сопоставленные колонки таблицы, поскольку они необходимы во внешнем SELECT, если внешний SELECT использует эти колонки; однако отложенные атрибуты, ссылающиеся на составленное SQL-выражение, как мы обычно делаем сcolumn_property()
, не будут частью подзапроса, поскольку они могут быть выбраны явно, если это необходимо в подзапросе. Если сущность выбирается из этого подзапроса, то выражение столбца может по-прежнему отображаться «снаружи» в терминах производных столбцов подзапроса. По сути, это приводит к такому же поведению, как и при работе с 1.3. Однако в этом случае исправление также должно гарантировать, что коллекция.selected_columns
в ORM-совместимомselect()
также следует этим правилам, что, в частности, позволяет корректно отображать рекурсивные CTE, которые ранее не отображались из-за этой проблемы.References: #6661
sql¶
Исправлена проблема в конструкциях CTE, в основном относящаяся к случаям использования ORM, когда рекурсивный CTE против «анонимных» меток, таких как те, что встречаются в отображениях ORM
column_property()
, приводил в секциюWITH RECURSIVE xyz(...)
их сырую внутреннюю метку, а не чистое анонимизированное имя.References: #6663
mypy¶
Исправлена проблема в плагине mypy, когда информация о классе для пользовательской декларативной базы не обрабатывалась корректно при кэшировании передачи mypy, что приводило к возникновению ошибки AssertionError.
References: #6476
asyncio¶
Реализация
async_scoped_session
позволила устранить некоторые асинхронные несовместимости междуscoped_session
иAsyncSession
, при которых некоторые методы (в частности, методasync_scoped_session.remove()
) должны использоваться с ключевым словомawait
.См.также
References: #6583
Исправлена ошибка в реализации asyncio, когда система адаптации greenlet не распространяла подклассы
BaseException
, в частности, включаяasyncio.CancelledError
, на логику обработки исключений, используемую движком для аннулирования и очистки соединения, что не позволяло корректно избавляться от соединений при отмене задачи.References: #6652
postgresql¶
Исправлена проблема, при которой тип данных
INTERVAL
в PostgreSQL и Oracle выдавал результатAttributeError
при использовании в контексте операции сравнения с объектомtimedelta()
. Pull request любезно предоставлен MajorDallas.References: #6649
Исправлена проблема, когда функция пула «pre ping» неявно запускала транзакцию, что при использовании драйвера psycopg2 мешало использованию пользовательских транзакционных флагов, таких как режим «только чтение» PostgreSQL.
References: #6621
mysql¶
mssql¶
Внесены улучшения в regexp версии сервера, используемый диалектом pymssql, для предотвращения переполнения regexp в случае некорректной строки версии.
Исправлена ошибка, при которой функция «schema_translate_map» некорректно работала при INSERT в таблицу с колонкой IDENTITY, когда в значениях INSERT указывалось значение колонки IDENTITY, что приводило к срабатыванию функции SQLAlchemy по установке IDENTITY INSERT в значение «on»; именно при такой директиве карта перевода схемы не выполнялась.
References: #6658
1.4.18¶
Released: June 10, 2021orm¶
Уточнено текущее назначение флага
relationship.bake_queries
, который в 1.4 используется для включения или отключения «лямбда-кэширования» операторов в рамках стратегий загрузчика «lazyload» и «selectinload»; он отделен от более фундаментального кэша SQL-запросов, который используется для большинства операторов. Кроме того, ленивый загрузчик больше не использует свой собственный кэш для SQL-запросов типа «многие к одному», что было причудой реализации, не существующей ни для одного другого сценария загрузчика. Наконец, убрано предупреждение «lru cache», которое могли выдавать стратегии lazyloader и selectinloader при работе с широким набором комбинаций классов/отношений; по результатам анализа некоторых примеров конечных пользователей это предупреждение не свидетельствует о наличии каких-либо серьезных проблем. Хотя установка значенияbake_queries=False
для такого отношения приведет к удалению этого кэша из использования, особого выигрыша в производительности в этом случае не будет, так как использование отсутствия кэширования по сравнению с использованием кэша, который необходимо часто обновлять, скорее всего, все же выигрывает в пользу используемого кэширования.Скорректирован способ генерации классов
scoped_session
иAsyncSession
из базового классаSession
, в результате чего пользовательские подклассыSession
, например, используемые в Flask-SQLAlchemy, не нуждаются в реализации позиционных аргументов при обращении к методу суперкласса и могут продолжать использовать те же стили аргументов, что и в предыдущих версиях.References: #6285
Исправлена проблема, когда при составлении запроса для объединенной выгрузки со сложной левой стороной, включающей наследование объединенных таблиц, мог не сформироваться корректный запрос из-за проблемы с адаптацией клаузул.
References: #6595
Исправлена регрессия, связанная с тем, как ORM преобразовывает заданный сопоставленный столбец в строку результата, когда в таких случаях, как объединенная ускоренная загрузка, мог происходить несколько более дорогой «откат» для установки этого разрешения из-за некоторой логики, которая была удалена с версии 1.3. Эта проблема также может приводить к выдаче предупреждений об устаревании, связанных с разрешением столбцов, при использовании запросов в стиле 1.4 с объединенной ускоренной загрузкой.
References: #6596
Исправлена ошибка в экспериментальном сценарии «select ORM objects from INSERT/UPDATE», при которой возникала ошибка, если оператор был направлен на подкласс, наследующий одну таблицу.
References: #6591
Предупреждение, выдаваемое для
relationship()
, когда несколько отношений будут пересекаться друг с другом по атрибутам внешних ключей, теперь включает специальный аргумент «overlaps», который необходимо использовать для каждого предупреждения, чтобы заглушить предупреждение без изменения отображения.References: #6400
asyncio¶
Реализована новая архитектура реестра, позволяющая находить
Async
версию объекта, напримерAsyncSession
,AsyncConnection
и т.д., по проксированному «синхронному» объекту, т.е.Session
,Connection
. Ранее, при использовании таких функций поиска, объектAsync
каждый раз создавался заново, что было не совсем удобно, так как идентичность и состояние объекта «async» не сохранялись при всех вызовах.Отсюда появились новые вспомогательные функции
async_object_session()
,async_session()
, а также новый атрибутInstanceState
InstanceState.async_session
, которые используются для получения исходногоAsyncSession
, связанного с ORM mapped object,Session
, связанного сAsyncSession
, иAsyncSession
, связанного сInstanceState
, соответственно.В этом патче также реализованы новые методы
AsyncSession.in_nested_transaction()
,AsyncSession.get_transaction()
,AsyncSession.get_nested_transaction()
.References: #6319
Исправлена проблема, возникавшая при использовании
NullPool
илиStaticPool
с асинхронным движком. В основном это касалось диалекта aiosqlite.References: #6575
Добавлены
asyncio.exceptions.TimeoutError
,asyncio.exceptions.CancelledError
как так называемые «исключения выхода» - класс исключений, включающий в себя такие события, какGreenletExit
иKeyboardInterrupt
, которые рассматриваются как события, позволяющие считать соединение DBAPI находящимся в непригодном состоянии и подлежащим утилизации.References: #6592
postgresql¶
Исправлена регрессия, при которой использование структуры PostgreSQL «INSERT..ON CONFLICT» не работало с драйвером psycopg2, если она использовалась в контексте «executemany» вместе со связанными параметрами в предложении «SET», из-за неявного использования помощников быстрого выполнения psycopg2, которые не подходят для такого типа оператора INSERT; поскольку в версии 1.4 эти помощники используются по умолчанию, это фактически является регрессией. Были добавлены дополнительные проверки, исключающие использование такого типа операторов в данном конкретном расширении.
References: #6581
sqlite¶
Добавить примечание относительно прагм, связанных с шифрованием, для pysqlcipher, передаваемого в url.
This change is also backported to: 1.3.25
References: #6589
Исправление для pysqlcipher, выпущенное в версии 1.4.3 #5848, к сожалению, оказалось нерабочим, так как новый хук
on_connect_url
ошибочно не получал объектURL
при нормальном использованииcreate_engine()
, а получал необработанную строку; тестовый набор не смог полностью установить реальные условия, при которых вызывается этот хук. Это было исправлено.References: #6586
1.4.17¶
Released: May 29, 2021orm¶
Исправлена регрессия, вызванная только что выпущенным исправлением производительности, упомянутым в #6550, когда запрос query.join() к отношению мог выдать ошибку AttributeError, если запрос выполнялся только к не-ORM структурам, что является довольно необычным шаблоном вызова.
References: #6558
1.4.16¶
Released: May 28, 2021general¶
orm¶
Исправлена проблема, когда при использовании параметра
relationship.cascade_backrefs
, установленного в значениеFalse
, которое в соответствии с поведение cascade_backrefs deprecated для удаления в 2.0 станет стандартным поведением в SQLAlchemy 2.0, добавление элемента в коллекцию, которая является уникальной, напримерset
илиdict
, не вызывало каскадного события, если объект уже был связан в этой коллекции через обратную ссылку. Это исправление представляет собой фундаментальное изменение механики работы с коллекциями, поскольку вводит новое состояние события, которое может срабатывать при мутации коллекции, даже если в ней не происходит никаких изменений; для этого действия теперь используется новый крючок событияAttributeEvents.append_wo_mutation()
.References: #6471
Исправлена регрессия, связанная с адаптацией выражения для маркированных составных элементов ORM, таких как выражения дискриминатора наследования одной таблицы с условными знаками или CASE-выражения, которая могла привести к некорректной адаптации псевдослучайных выражений, например, используемых в операциях join / joinedload в ORM, например, к ссылке на неправильную таблицу в предложении ON в соединении.
Это изменение также устраняет недостаток производительности, который возникал в процессе вызова
Select.join()
с указанием ORM-атрибута в качестве цели.References: #6550
Исправлена регрессия, при которой полная комбинация объединенного наследования, глобальных отношений with_polymorphic, самореферентных отношений и объединенной загрузки не могла выдать запрос с областью действия ленивых загрузок и операций обновления объектов, которые также пытались вывести объединенный загрузчик.
References: #6495
Усовершенствованы правила разрешения привязок для
Session.execute()
таким образом, чтобы при построении не-ORM утверждения, например, конструкцииinsert()
, тем не менее, против ORM-объектов, для разрешения привязки в максимально возможной степени использовалась ORM-сущность, например, дляSession
, у которого карта привязок настроена на общий суперкласс без конкретных мапперов или таблиц, названных в карте.References: #6484
engine¶
Исправлена проблема, при которой знак
@
в части URL, посвященной базе данных, не интерпретировался корректно, если URL также содержал секцию username:password.References: #6482
Исправлена давняя проблема с
URL
, когда параметры запроса, следующие за вопросительным знаком, не обрабатывались корректно, если URL не содержал части базы данных с обратной косой чертой.References: #6329
sql¶
Исправлена регрессия в стратегии динамического загрузчика и
relationship()
в целом, когда параметрrelationship.order_by
хранился в виде изменяемого списка, который затем мог быть изменен при использовании дополнительных методов «order_by», применяемых к объекту динамического запроса, что приводило к повторяющемуся росту критериев ORDER BY.References: #6549
mssql¶
misc¶
Исправлено предупреждение об устаревании, выдававшееся при использовании
automap_base()
без передачи существующегоBase
.References: #6529
Убрать из кода типы pep484. В настоящее время усилия направлены на пакет stub, а наличие типов в двух местах ухудшает ситуацию, так как типы в исходниках SQLAlchemy обычно устарели по сравнению с версиями в stubs.
References: #6461
Исправлена регрессия в расширении
sqlalchemy.ext.instrumentation
, из-за которой утилизация инструментария не работала полностью. Данное исправление включает в себя как исправление регрессии в версии 1.4, так и исправление связанной с ней проблемы, которая существовала и в версии 1.3. В рамках этого изменения классsqlalchemy.ext.instrumentation.InstrumentationManager
теперь имеет новый методunregister()
, который заменяет предыдущий методdispose()
, который не вызывался начиная с версии 1.4.References: #6390
1.4.15¶
Released: May 11, 2021general¶
В системе предупреждений SQLAlchemy был применен новый подход, позволяющий точно предсказывать соответствующий уровень стека для каждого предупреждения в динамическом режиме. Это позволяет более просто оценивать источник предупреждений, генерируемых SQLAlchemy, и предупреждений об устаревании, поскольку предупреждение будет указывать на исходную строку в коде конечного пользователя, а не на произвольный уровень в собственном коде SQLAlchemy.
References: #6241
orm¶
Исправлена дополнительная регрессия, вызванная функцией #1763 «eager loaders run on unexpire», когда функция запускалась для опции
contains_eager()
eagerload в случае, еслиcontains_eager()
были соединены с дополнительной опцией eager loader, что приводило к некорректному запросу, поскольку исходные критерии объединения, связанные с запросом, больше не присутствовали.References: #6449
Исправлена проблема в стратегии загрузчика подзапросов, из-за которой кэширование не работало корректно. В результате в логах для всех выдаваемых SQL-запросов с загрузкой подзапросов вместо «кэшировано» появлялось сообщение «сгенерировано», что, насыщая кэш новыми ключами, снижало общую производительность, а также выдавало предупреждения «LRU size alert».
References: #6459
sql¶
В 1.4.12 была скорректирована логика, добавленная в #6397 в 1.4.12, таким образом, чтобы внутренняя мутация объекта
BindParameter
происходила на этапе конструирования клаузы, как это было раньше, а не на этапе компиляции. В последнем случае мутация по-прежнему вызывала побочные эффекты по отношению к входящей конструкции и, кроме того, могла потенциально вмешиваться в работу других внутренних процедур мутации.References: #6460
mysql¶
Добавлена поддержка параметра
ssl_check_hostname=
в URI соединений mysql и обновлена документация по диалекту mysql, касающаяся безопасных соединений. Оригинальный pull request любезно предоставлен Jerry Zhao.References: #5397
1.4.14¶
Released: May 6, 2021orm¶
Исправлена регрессия, связанная с использованием загрузчика
lazy='dynamic'
в сочетании с отсоединенным объектом. Прежнее поведение заключалось в том, что динамический загрузчик при вызове методов типа.all()
возвращал пустые списки для отсоединенных объектов без ошибок, это было восстановлено, однако теперь выдается предупреждение, так как это не является корректным результатом. Другие сценарии динамического загрузчика корректно возвращаютDetachedInstanceError
.References: #6426
engine¶
Применено согласованное поведение для случая вызова
.commit()
или.rollback()
внутри существующего менеджера контекста.begin()
, с добавлением потенциальной возможности выдачи SQL внутри блока после фиксации или отката. Это изменение продолжает изменение, впервые добавленное в #6155, где было предложено использовать случай вызова «отката» внутри блока контекстного менеджера.begin()
:вызов
.commit()
или.rollback()
теперь будет разрешен без ошибок и предупреждений во всех диапазонах, включая унаследованные и будущиеEngine
, ORMSession
, asyncioAsyncEngine
. РанееSession
запрещал это делать.Оставшаяся область действия менеджера контекста закрывается; при завершении блока выдается проверка, не была ли транзакция уже завершена, и если да, то блок возвращается без каких-либо действий.
Теперь будет возникать ошибка, если внутри блока, после вызова
.commit()
или.rollback()
, будет выдан последующий SQL любого вида. Блок должен быть закрыт, так как в противном случае состояние исполняемого объекта в этом состоянии будет неопределенным.
References: #6288
Для поддержки устаревших шаблонов, используемых в пакете «records», а также в других немигрирующих приложениях, установлен путь устаревания вызова метода
CursorResult.keys()
для оператора, не возвращающего строк. Ранее метод вызывал безусловную ошибкуResourceClosedException
, как и при попытке получить строки. Хотя это правильное поведение и в дальнейшем, объектLegacyCursorResult
в этом случае будет возвращать пустой список для.keys()
, как это было в версии 1.3, а также выдавать предупреждение об устаревании версии 2.0. Объект_cursor.CursorResult
, используемый при использовании движка «будущего» в стиле 2.0, будет продолжать возвращать пустой список, как и сейчас.References: #6427
sql¶
Исправлена регрессия, вызванная изменением «empty in», только что внесенным в #6397 1.4.12, где для случая использования «not in» выражение должно быть заключено в круглые скобки, иначе условие будет мешать другим критериям фильтрации.
References: #6428
Класс
TypeDecorator
теперь будет выдавать предупреждение при использовании в SQL-компиляции с кэшированием, если флаг.cache_ok
не установлен в значениеTrue
илиFalse
. На уровне класса можно установить новый атрибутTypeDecorator.cache_ok
, который будет свидетельствовать о том, что все параметры, передаваемые объекту, безопасны для использования в качестве ключа кэша, если установлено значениеTrue
,False
означает, что нет.References: #6436
1.4.13¶
Released: May 3, 2021orm¶
Исправлена ошибка в стратегии загрузчика
selectinload
, из-за которой он некорректно кэшировал свое внутреннее состояние при работе с отношениями, объединяющими более одного столбца, например, при использовании составного внешнего ключа. Некорректное кэширование приводило к сбою других несвязанных операций загрузчика.References: #6410
Исправлена ошибка, при которой
Query.filter_by()
не работал, если ведущей сущностью была SQL-функция или другое выражение, производное от первичной сущности, а не простая сущность или колонка этой сущности. Кроме того, улучшено поведениеSelect.filter_by()
в целом для работы с выражениями столбцов даже в контексте, отличном от нормального.References: #6414
Исправлена ошибка, при которой использование
selectinload()
иsubqueryload()
для загрузки пути глубиной в два уровня приводило к ошибке атрибута.References: #6419
Исправлена ошибка, при которой использование стратегии загрузчика
noload()
в сочетании с «динамическим» отношением приводило к ошибке атрибута, поскольку стратегия noload пыталась применить себя к динамическому загрузчику.References: #6420
engine¶
Восстановлено устаревшее транзакционное поведение, которое было случайно удалено из
Connection
, поскольку в предыдущих версиях оно не тестировалось как известный случай использования, когда вызов методаConnection.begin_nested()
при отсутствии транзакции вообще не создает SAVEPOINT, а вместо этого запускает внешнюю транзакцию, возвращая объектRootTransaction
вместо объектаNestedTransaction
. После фиксации этаRootTransaction
будет выдавать реальный COMMIT на соединение с базой данных. Ранее во всех случаях присутствовало поведение в стиле 2.0, которое автозапускало транзакцию, но не фиксировало ее, что является поведенческим изменением.При использовании объекта соединения 2.0 style поведение не изменилось по сравнению с предыдущими версиями 1.4; вызов
Connection.begin_nested()
«автозапускает» внешнюю транзакцию, если она еще не существует, а затем, согласно инструкции, выдает SAVEPOINT, возвращая объектNestedTransaction
. Внешняя транзакция фиксируется вызовомConnection.commit()
, как и положено при использовании стиля «commit-as-you-go».В режиме, отличном от «будущего», старое поведение восстанавливается, но при этом выдается предупреждение об устаревании в версии 2.0, поскольку это унаследованное поведение.
References: #6408
asyncio¶
Исправлена регрессия, связанная с тем, что при инстанцировании движка async до запуска любого цикла asyncio создавался цикл #6337, который
asyncio.Lock
мог быть присоединен к неправильному циклу, что приводило к сообщению об ошибке asyncio при попытке использования движка в определенных обстоятельствах.References: #6409
postgresql¶
Добавлена поддержка курсоров на стороне сервера в диалекте pg8000 для PostgreSQL. Это позволяет использовать опцию
Connection.execution_options.stream_results
.References: #6198
1.4.12¶
Released: April 29, 2021orm¶
Исправлена ошибка в
Session.bulk_save_objects()
при использовании с постоянными объектами, из-за которой не удавалось отследить первичный ключ в сопоставлениях, где имя столбца первичного ключа отличалось от имени атрибута.This change is also backported to: 1.3.25
References: #6392
Исправлена критическая регрессия, при которой отслеживание связанных параметров, используемое в системе кэширования SQL, не позволяло отследить все параметры в случае, когда одно и то же SQL-выражение, содержащее параметр, использовалось в ORM-запросе с использованием такой функции, как наследование классов, а затем встраивалось в объемлющее выражение, в котором это же выражение использовалось несколько раз, например, в UNION. При компиляции с наследованием классов ORM по отдельности копирует отдельные операторы SELECT, которые затем встраиваются во вложенное выражение и не учитывают все параметры. Логика, отслеживающая это условие, была скорректирована для работы с несколькими копиями параметра.
References: #6391
Исправлены две разные проблемы, в основном затрагивающие
hybrid_property
, которые возникали при распространенных сценариях неправильной конфигурации, которые в 1.3 молчаливо игнорировались, а в 1.4 стали неудачными, когда реализация «выражения» возвращала неClauseElement
, например, булево значение. В обоих случаях поведение 1.3 заключалось в молчаливом игнорировании неправильной конфигурации и попытке интерпретировать значение как SQL-выражение, что приводило к некорректному запросу.Исправлена проблема взаимодействия системы атрибутов с hybrid_property, когда если метод
__clause_element__()
атрибута возвращал не:class:_sql.ClauseElement объект, то внутреннийAttributeError
приводил к тому, что атрибут возвращал функциюexpression
на самом hybrid_property, так как ошибка атрибута была против имени.expression
, которое вызывало метод__getattr__()
в качестве запасного варианта. Теперь это происходит в явном виде. В версии 1.3 не:class:_sql.ClauseElement возвращалось напрямую.Исправлена проблема в системе принуждения к аргументам SQL, когда передача объекта неправильного типа в методы, ожидающие выражения столбцов, приводила к ошибке, если объект вообще не являлся объектом SQLAlchemy, например, функцией Python, в случаях, когда объект не был просто принудительно приведен к связанному значению. Опять же, в 1.3 не было полноценной системы принудительного приведения аргументов, поэтому этот случай также прошел бы молча.
References: #6350
Исправлена проблема, при которой использование
Select
в качестве подзапроса в контексте ORM приводило к модификацииSelect
, отключая eagerload для этого объекта, что при повторном использовании этого в контексте выполнения на верхнем уровне приводило к тому, что этот жеSelect
не загружался eagerload.References: #6378
Исправлена проблема, при которой новое поведение autobegin не приводило к «автозапуску» в случае изменения атрибутов существующего постоянного объекта, что влияло на поведение
Session.rollback()
, поскольку не создавался снимок для отката. Механика «изменения атрибутов» была обновлена, чтобы обеспечить «автозапуск», который не выполняет никакой работы с базой данных, при изменении атрибутов персистентного объекта таким же образом, как и при вызовеSession.add()
. Это регресс, поскольку в версии 1.3 метод rollback() всегда имел транзакцию для отката и каждый раз завершался.Исправлена ошибка в ORM, когда использование свойства hybrid для указания выражения из другой сущности запутывало логику маркировки столбцов в ORM и пыталось вывести имя hybrid из другого класса, что приводило к ошибке атрибута. Теперь класс-владелец гибридного атрибута отслеживается вместе с именем.
References: #6386
Исправлена регрессия в hybrid_property, когда гибрид против SQL-функции в некоторых случаях выдавал ошибку
AttributeError
при попытке сгенерировать запись для коллекции.c
подзапроса; помимо прочего, это влияло на его использование в случаях, подобныхQuery.count()
.References: #6401
Скорректировано декларативное сканирование для классов данных таким образом, чтобы поведение наследования
declared_attr()
, установленного для миксина, при использовании новой формы, когда он находится внутри конструкцииdataclasses.field()
, а не является дескрипторным атрибутом класса, корректно учитывало случай, когда целевой класс, подлежащий отображению, является подклассом существующего отображенного класса, который уже отобразил этотdeclared_attr()
, и поэтому не должен быть повторно применен к этому классу.References: #6346
Исправлена проблема с методом (устаревшим в 1.4)
ForeignKeyConstraint.copy()
, который приводил к ошибке при вызове с аргументомschema
.References: #6353
engine¶
Исправлена проблема, при которой использование явного выражения
Sequence
приводило к непоследовательному поведению «inline» для конструкцииInsert
, включающей несколько фраз значений; первый seq был inline, а последующие - «pre-execute», что приводило к непоследовательному упорядочиванию последовательности. Теперь выражения последовательности полностью инлайновые.References: #6361
sql¶
Пересмотрено выражение «EMPTY IN», которое больше не зависит от использования подзапроса, так как это вызывало некоторые проблемы с совместимостью и производительностью. Новый подход для выбранных баз данных использует преимущества использования выражения IN с возвратом NULL в сочетании с обычным выражением «1 != 1» или «1 = 1», дополненным операторами AND или OR. Это выражение теперь используется по умолчанию для всех бэкендов, кроме SQLite, который все еще имел некоторые проблемы совместимости с кортежами «IN» для старых версий SQLite.
Сторонние диалекты по-прежнему могут переопределять отображение выражения «пустое множество», реализуя новый метод компилятора
def visit_empty_set_op_expr(self, type_, expand_op)
, который имеет приоритет над существующимdef visit_empty_set_expr(self, element_types)
, который остается в силе.Исправлена ошибка, при которой использование конструкции
text()
внутри предложения columns конструкцииSelect
, для которой лучше использовать конструкциюliteral_column()
, тем не менее, не позволяло корректно работать конструкциям типаunion()
. Другие случаи использования, например, построение подзапросов, продолжают работать так же, как и в предыдущих версиях, где конструкцияtext()
молча опускается из коллекции экспортируемых столбцов. Также исправлено аналогичное использование в ORM.References: #6343
Исправлена регрессия, связанная с устаревшими методами, такими как
Select.append_column()
, при которой внутренние утверждения не выполнялись.References: #6261
Исправлена регрессия, вызванная #5395, когда отстройка проверки последовательностей в
select()
приводила к сбоям при выполнении запросов в стиле 2.0 с отображенным классом, который также имеет метод__iter__()
. Настроил проверку еще раз, чтобы учесть это, а также некоторые другие интересные сценарии__iter__()
.References: #6300
schema¶
Убедитесь, что диалект MySQL и MariaDB игнорирует конструкцию
Identity
при отображении ключевого словаAUTO_INCREMENT
в таблице create.Обновлен компилятор Oracle и PostgreSQL, который не выводит
Identity
, если версия базы данных его не поддерживает (Oracle < 12 и PostgreSQL < 10). Ранее он отображался независимо от версии базы данных.References: #6338
postgresql¶
Исправлена очень старая проблема, из-за которой тип данных
Enum
не наследовал параметрMetaData.schema
объектаMetaData
, когда этот объект передавался вEnum
с помощьюEnum.metadata
.References: #6373
sqlite¶
По умолчанию используется пул
SingletonThreadPool
для баз данных in-memory SQLite, созданных с использованием имен файлов URI. Ранее по умолчанию использовался пулNullPool
, который предполагал совместное использование одной и той же базы данных несколькими движками.References: #6379
mssql¶
Добавить поддержку
TypeEngine.as_generic()
для столбцовsqlalchemy.dialects.mysql.BIT
, отображая их наBoolean
.References: #6345
Исправлена регрессия, вызванная появлением #6306, добавившего поддержку
DateTime(timezone=True)
, при которой прежнее поведение драйвера pyodbc, заключавшееся в неявном сбросе tzinfo из даты с учетом временной зоны при INSERT в колонку DATETIME с учетом временной зоны, терялось, что приводило к ошибке SQL Server при вставке объектов с учетом временной зоны в колонки базы данных, не учитывающие временную зону.References: #6366
1.4.11¶
Released: April 21, 2021orm declarative¶
Исправлена регрессия, в результате которой недавние изменения в поддержке классов данных Python приводили к тому, что класс, сопоставленный с ORM, не мог успешно переопределить метод
__new__()
.References: #6331
engine¶
1.4.10¶
Released: April 20, 2021orm¶
Изменено поведение, исправленное в #6232, где стратегия загрузчика
immediateload
больше не входит в рекурсивные циклы; модификация заключается в том, что при нетерпеливой загрузке (joinedload, selectinload или subqueryload) из A->bs->B, которая затем указываетimmediateload
для простого manytoone B->a->A, находящегося в карте идентификации, заполняется B->A, так что этот атрибут снова заполняется при загрузке коллекции A/A.bs. Это позволяет объектам быть функциональными при отсоединении.Исправлена ошибка в новой функции
with_loader_criteria()
, когда при использовании класса mixin сdeclared_attr()
на атрибуте, к которому обращались внутри пользовательской лямбды, выдавалось предупреждение об использовании не отображенного объявленного атрибута при первой инициализации вызываемой лямбды. Теперь это предупреждение предотвращается с помощью специального инструментария для этого шага инициализации лямбды.References: #6320
Исправлена дополнительная регрессия, вызванная функцией «eagerloaders on refresh», добавленной в #1763, где операция обновления исторически устанавливала флаг
populate_existing
, который, учитывая новую функцию, теперь перезаписывает ожидающие изменения в нетерпеливо загруженных объектах, когда autoflush равен false. Флаг populate_existing для этого случая был отключен, и для обеспечения обновления нужных атрибутов был использован более специфический метод.References: #6326
Исправлена проблема при использовании стиля выполнения 2.0, которая не позволяла использовать
Result.scalar_one()
илиResult.scalar_one_or_none()
после вызоваResult.unique()
для случая, когда ORM в любом случае возвращает одноэлементную строку.References: #6299
sql¶
Исправлена проблема в компиляторе SQL, когда связанные параметры, заданные для конструкции
Values
, не отслеживались позиционно, если находились внутри конструкцииCTE
, что негативно сказывалось на драйверах баз данных, поддерживающих VALUES + ctes и использующих позиционные параметры, в частности, SQL Server, а также asyncpg. Также исправлена поддержка флагов компилятора, таких какliteral_binds
.References: #6327
Исправлены и устранены проблемы, связанные с пользовательскими функциями и другими произвольными конструкциями выражений, которые в рамках механики маркировки столбцов SQLAlchemy пытались использовать
str(obj)
для получения строкового представления для использования в качестве анонимного имени столбца в коллекции.c
подзапроса. Это очень устаревшее поведение, которое плохо работает и приводит к множеству проблем, поэтому оно было изменено, чтобы больше не выполнять компиляцию путем создания специальных методов наFunctionElement
для обработки этого случая, так как функции SQL являются единственным случаем, когда оно используется. Следствием такого поведения является то, что немаркированному столбцовому выражению без производного имени будет присваиваться произвольная метка, начинающаяся с префикса"_no_label"
в коллекции.c
подзапроса; ранее они представлялись либо как общая структуризация этого выражения, либо как внутренний символ.References: #6256
schema¶
Исправлена проблема, при которой тип
next_value()
не выводился из соответствующего типаSequence
, а вместо этого жестко кодировался вInteger
. Теперь используется конкретный числовой тип.References: #6287
mypy¶
Исправлена проблема, при которой плагин mypy некорректно интерпретировал явную аннотацию
Mapped
в сочетании с аннотациейrelationship()
, ссылающейся на класс по строковому имени; корректная аннотация понижалась до менее конкретной, что приводило к ошибкам при наборе текста.References: #6255
mssql¶
Параметр
DateTime.timezone
при установке значенияTrue
теперь будет использовать тип столбцаDATETIMEOFFSET
в SQL Server при эмуляции DDL, а неDATETIME
, где флаг молча игнорировался.References: #6306
misc¶
Исправлена ошибка
instrument_declarative()
, вызывающая несуществующий метод реестра.References: #6291
1.4.9¶
Released: April 17, 2021orm¶
Установлена поддержка
synoynm()
в сочетании с гибридным свойством, полностью настроен assocaitionproxy, в том числе могут быть созданы синонимы, связывающие эти конструкции, которые полностью работают. Ранее такое поведение было полуявно запрещено, но поскольку оно не во всех случаях давало сбой, была добавлена явная поддержка assoc proxy и гибридов.References: #6267
Исправлена критическая проблема производительности, когда при обходе конструкции
select()
выполнялся обход повторяющегося произведения представленных предложений FROM, поскольку каждое из них ссылалось на столбцы в предложении columns; для серии вложенных подзапросов с большим количеством столбцов это могло привести к большой задержке и значительному увеличению памяти. Этот обход используется множеством SQL- и ORM-функций, включая ORMSession
, когда он настроен на «table-per-bind», и хотя это не самый распространенный случай использования, похоже, что Flask-SQLAlchemy жестко закодирован на его использование, поэтому проблема затрагивает пользователей Flask-SQLAlchemy. Обход был исправлен на унификацию в предложениях FROM, что, по сути, неявно происходило в архитектуре до версии 1.4.References: #6304
Исправлена ошибка, при которой атрибут, сопоставленный с
synonym()
, не мог быть использован в опциях загрузчика колонок, таких какload_only()
.References: #6272
sql¶
Исправлена ошибка, при которой пустой оператор in для кортежа приводил к ошибке при компиляции с опцией
literal_binds=True
.References: #6290
postgresql¶
Исправлена ошибка аргумента в компиляторах default и PostgreSQL, которая мешала выполнению оператора UPDATE..FROM или DELETE..FROM..USING, из которого затем производился выбор в виде CTE.
References: #6303
1.4.8¶
Released: April 15, 2021orm¶
Исправлена утечка кэша, связанная с опцией загрузчика
with_expression()
, когда заданное SQL-выражение некорректно рассматривалось как часть ключа кэша.Кроме того, исправлена регрессия, связанная с соответствующей функцией
query_expression()
. Хотя технически эта ошибка существует и в 1.3, она была обнаружена только в 1.4. Значение «expr по умолчанию»null()
приводилось, когда оно не требовалось, а также не адаптировалось корректно, когда ORM переписывала выражения, например, при использовании объединенной ускоренной загрузки. Исправление гарантирует, что «одиночные» выражения типаNULL
иtrue
не будут «адаптированы» для ссылок на столбцы в ORM-выражениях, а также гарантирует, чтоquery_expression()
без выражения по умолчанию не будет отображаться в выражении, еслиwith_expression()
не используется.References: #6259
Исправлена проблема, связанная с новой функцией
Session.refresh()
, введенной в #1763, когда нетерпеливо загруженные отношения также обновляются, когда стратегии загрузчикаlazy="raise"
иlazy="raise_on_sql"
мешали стратегии загрузчикаimmediateload()
, что нарушало работу функции для отношений, которые были загружены с помощью , , а также для отношений, загруженных с помощьюselectinload()
,subqueryload()
.References: #6252
engine¶
Метод
Dialect.has_table()
теперь вызывает информативное исключение, если ему передается не-Connection, поскольку такое некорректное поведение, по-видимому, встречается часто. Этот метод не предназначен для использования вне диалекта. Пожалуйста, используйте методInspector.has_table()
или для кросс-совместимости со старыми версиями SQLAlchemy методEngine.has_table()
.
sql¶
Кортеж, возвращаемый командой
CursorResult.inserted_primary_key
, теперь представляет собой объектRow
с именованным интерфейсом поверх существующего интерфейса tuple.References: #3314
Исправлена ошибка, при которой объект
BindParameter
не отображался должным образом для выражения IN (т.е. при использовании функции «post compile» в 1.4), если объект копировался из внутренней операции клонирования или из операции pickle, а имя параметра содержало пробелы или другие специальные символы.References: #6249
Исправлена регрессия, при которой введение синтаксиса INSERT «INSERT… VALUES (DEFAULT)» не поддерживался некоторыми бэкендами, которые, однако, поддерживают «INSERT..DEFAULT VALUES», включая SQLite. Теперь эти два синтаксиса поддерживаются или не поддерживаются отдельно для каждого диалекта, например, MySQL поддерживает «VALUES (DEFAULT)», но не «DEFAULT VALUES». Также была включена поддержка Oracle.
References: #6254
mypy¶
Обновлен плагин Mypy, который теперь использует только публичный интерфейс плагина семантического анализатора.
Переработано исправление для
OrderingList
из версии 1.4.7, которое тестировалось на некорректном API.References: #6205
asyncio¶
Исправлена опечатка, из-за которой атрибут
bind
не мог установить правильное значение для атрибутаAsyncSession
.References: #6220
mssql¶
Исправлена дополнительная регрессия в той же области, что и в #6173, #6184, когда при использовании значения 0 для OFFSET в сочетании с LIMIT в SQL Server создавался оператор, использующий «TOP», как это было в 1.3, однако из-за кэширования он не реагировал соответствующим образом на другие значения OFFSET. Если «0» не было первым, то все было бы в порядке. Для исправления, синтаксис «TOP» теперь выдается только в том случае, если значение OFFSET опущено полностью, то есть не используется
Select.offset()
. Обратите внимание, что это изменение требует, чтобы при использовании модификаторов «with_ties» или «percent» в операторе нельзя было указывать значение OFFSET, равное нулю, теперь его нужно опускать полностью.References: #6265
1.4.7¶
Released: April 9, 2021orm¶
Исправлена ошибка, при которой стратегия загрузчика
subqueryload()
не могла корректно учитывать вложенные опции, например, опциюdefer()
в столбце, если «путь» загрузки подзапроса был более чем на один уровень глубже.References: #6221
Исправлена регрессия, при которой функция
merge_frozen_result()
, используемая в примере dogpile.caching, не включалась в тесты и приводила к ошибкам из-за неверных внутренних аргументов.References: #6211
Исправлена критическая регрессия, при которой
Session
мог не начать «автозапуск» новой транзакции, когда происходил флэш без существующей транзакции, неявно переводяSession
в режим legacy autocommit, который фиксировал транзакцию. ВSession
теперь есть проверка, которая предотвращает возникновение этого состояния, в дополнение к устранению проблемы flush.Кроме того, уменьшена часть изменений, сделанных в рамках #5226, которые могут выполнять autoflush во время операции unexpire, чтобы не делать этого в случае
Session
, использующего унаследованный режимSession.autocommit
, поскольку это приводит к фиксации в рамках операции refresh.References: #6233
Исправлена ошибка, при которой схема компиляции ORM предполагала, что имя функции гибридного свойства совпадает с именем атрибута, в результате чего возникала ошибка
AttributeError
при попытке определить правильное имя для каждого элемента в кортеже результатов. Аналогичная проблема существует и в 1.3, но касается она только имен строк кортежа. Исправление добавляет проверку того, что имя функции гибрида действительно присутствует в__dict__
класса или его суперклассов, прежде чем присваивать это имя; в противном случае гибрид считается «безымянным», и кортежи результатов ORM будут использовать схему именования базового выражения.References: #6215
Исправлена критическая регрессия, вызванная новой функцией, добавленной в #1763, - вызов загрузчиков нетерпения на операциях unexpire. Новая возможность использует стратегию «немедленной загрузки» eager loader в качестве замены стратегии загрузки коллекции, которая, в отличие от других стратегий «после загрузки», не учитывала рекурсивные вызовы между взаимозависимыми отношениями, что приводило к ошибкам переполнения рекурсии.
References: #6232
engine¶
Исправлено поведение объекта
Row
при обращении к нему по словарю, т.е. преобразование в dict черезdict(row)
или обращение к его членам через строки или другие объекты, т.е.row["some_key"]
работает как в случае со словарем, а не вызываетTypeError
, как в случае с кортежем, независимо от наличия или отсутствия расширений Си. Изначально предполагалось, что для «небудущего» случая использованияLegacyRow
будет выдаваться предупреждение об устаревании версии 2.0, а для «будущего» классаRow
будет выдаваться предупреждениеTypeError
. Однако версияRow
на языке Си не могла выдать это предупреждениеTypeError
, и, чтобы усложнить ситуацию, методSession.execute()
теперь возвращаетRow
во всех случаях, чтобы сохранить согласованность с результатом ORM, поэтому пользователи, у которых не установлены расширения на языке Си, будут видеть другое поведение в этом единственном случае для существующего кода в стиле pre-1.4.Поэтому, чтобы смягчить общую схему обновления, поскольку большинство пользователей не сталкивались с более строгим поведением
Row
вплоть до версии 1.4.6,LegacyRow
иRow
обеспечивают как доступ по строковым ключам, так и поддержкуdict(row)
, во всех случаях выдавая предупреждение о депривации 2.0 при включенииSQLALCHEMY_WARN_20
. ОбъектRow
по-прежнему использует кортежеподобное поведение для__contains__
, что, пожалуй, является единственным заметным изменением в поведении по сравнению сLegacyRow
, если не считать удаления методовvalues()
иitems()
в стиле словаря.References: #6218
sql¶
Усовершенствована функция «расширения», используемая для операций
ColumnOperators.in_()
, позволяющая выводить тип выражения из правого списка элементов, если в левой части не задан явный тип. Это позволяет выражению, в частности, поддерживать строку. В версии 1.3 «расширение» не использовалось автоматически для выраженийColumnOperators.in_()
, так что в этом смысле данное изменение исправляет регрессию в поведении.References: #6222
Исправлен компилятор «stringify» для поддержки базовой структуризации «многорядного» оператора INSERT, т.е. такого, в котором после ключевого слова VALUES следует несколько кортежей.
schema¶
Исправлена ошибка, при которой использование в словаре
Connection.execution_options.schema_translate_map
лексем, содержащих специальные символы, такие как скобки, не приводило к корректной замене. Использование символов квадратных скобок[]
теперь явно запрещено, так как в текущей реализации они используются в качестве разделителя.References: #6216
mypy¶
Исправлена проблема в плагине Mypy, когда плагин не выводил правильный тип для столбцов подклассов, не восходящих непосредственно к
TypeEngine
, в частности, дляTypeDecorator
иUserDefinedType
.
tests¶
В
DefaultDialect
добавлен новый флагsupports_schemas
; сторонние диалекты могут установить этот флаг в значениеFalse
, чтобы отключить тесты SQLAlchemy на уровне схемы при запуске тестового набора для стороннего диалекта.
1.4.6¶
Released: April 6, 2021orm¶
Исправлена регрессия, при которой использовалась устаревшая форма
Query.join()
, передающая в одном вызовеQuery.join()
серию сущностей для объединения без условия ON, что приводило к некорректной работе.References: #6203
Исправлена критическая ошибка, когда метод
Query.yield_per()
в ORM настраивал внутреннийResult
для получения фрагментов за один раз, однако использовал новый методResult.unique()
, который унифицировал весь результат. Это привело бы к потере строк, так как ORM используетid(obj)
в качестве функции уникализации, что приводит к повторным идентификаторам новых объектов, так как уже виденные объекты собираются в мусор. В версии 1.3 «уникализация» выполнялась для каждого чанка, что на самом деле не дает «уникальных» результатов, когда результаты выдаются в виде чанков. Поскольку методQuery.yield_per()
уже явно запрещен, когда используется объединенная ускоренная загрузка, что является основным обоснованием функции «уникализации», теперь функция «уникализации» полностью отключается при использованииQuery.yield_per()
.Эта регрессия относится только к унаследованному объекту
Query
; при использовании исполнения 2.0 style «уникализация» автоматически не применяется. Чтобы предотвратить возникновение проблемы при явном использованииResult.unique()
, теперь при извлечении строк из «уникального» объектаResult
уровня ORM, если также используется какой-либо API yield per, будет выдаваться ошибка, так как назначениеyield_per
заключается в том, чтобы обеспечить произвольно большое количество строк, которые не могут быть уникализированы в памяти без увеличения количества записей до полного размера результата.References: #6206
sql¶
В версии 1.4.5 исправлены дальнейшие ошибки в той же области, что и в #6173, когда «посткомпиляционный» параметр, опять же наиболее часто используемый для визуализации LIMIT/OFFSET в Oracle и SQL Server, не обрабатывался корректно, если один и тот же параметр визуализировался в нескольких местах в операторе.
References: #6202
Выполнение
Subquery
с помощьюConnection.execute()
устарело и будет выдано предупреждение об устаревании; этот случай использования был упущением и должен был быть удален из версии 1.4. Теперь для обеспечения обратной совместимости операция будет выполнять непосредственно объектSelect
. Аналогично, классCTE
также не подходит для выполнения. В версии 1.3 попытка выполнить CTE приводила к выполнению некорректного «пустого» SQL-оператора; поскольку этот вариант использования был нерабочим, теперь он приводит к появлениюObjectNotExecutableError
. Ранее в 1.4 была попытка выполнить CTE как оператор, однако она работала нестабильно.References: #6204
schema¶
Объект
Table
теперь выдает информативное сообщение об ошибке, если он инстанцируется без позиционной передачи хотя бы аргументовTable.name
иTable.metadata
. Ранее, если они передавались как аргументы ключевого слова, то объект молча не инициализировался.This change is also backported to: 1.3.25
References: #6135
mypy¶
Применен ряд рефакторингов и исправлений для учета «инкрементального» режима работы Mypy с несколькими файлами, который ранее не учитывался. В этом режиме плагин Mypy должен учитывать, что типы данных Python, выраженные в других файлах, приходят с меньшим количеством информации, чем при прямом запуске.
Кроме того, добавлен новый декоратор
declarative_mixin()
, необходимый для того, чтобы плагин Mypy мог однозначно идентифицировать класс Declarative mixin, который в других случаях не используется в конкретном Python-файле.References: #6147
Исправлена проблема, при которой плагин Mypy не мог интерпретировать «класс_коллекции» отношения, если оно было вызываемым, а не классом. Также улучшено сопоставление типов и отчет об ошибках для отношений, ориентированных на коллекции.
References: #6205
asyncio¶
Добавлены аксессоры
.sqlstate
и синоним.pgcode
к атрибуту.orig
класса исключения SQLAlchemy, поднимаемого адаптером asyncpg DBAPI, то есть промежуточного объекта исключения, который оборачивается поверх исключения, поднимаемого самой библиотекой asyncpg, но ниже уровня диалекта SQLAlchemy.References: #6199
1.4.5¶
Released: April 2, 2021orm¶
Исправлена ошибка, при которой стратегия загрузчика
joinedload()
не приводила к успешной загрузке в маппер, который сопоставляется с конструкциейCTE
.References: #6172
Уменьшено предупреждение, добавленное в #5171, чтобы не предупреждать о перекрытии столбцов в сценарии наследования, когда конкретное отношение является локальным для подкласса и поэтому не представляет собой перекрытия.
References: #6171
sql¶
Исправлена ошибка в новой функции
FunctionElement.render_derived()
, когда имена колонок, явно выводимые в псевдониме SQL, не имели правильного кавычек для имен, чувствительных к регистру, и других неалфавитно-цифровых имен.References: #6183
Исправлена ошибка, при которой использование метода
Operators.in_()
с объектомSelect
против столбца, не связанного с таблицей, приводило к появлениюAttributeError
, или, в более общем случае, использованиеScalarSelect
, не имеющего типа данных, в двоичном выражении приводило к некорректному состоянию.References: #6181
В класс
Dialect
добавлен новый флагDialect.supports_statement_cache
. Теперь этот флаг должен присутствовать непосредственно в классе диалекта для того, чтобы SQLAlchemy query cache вступил в силу для этого диалекта. Это обосновано тем, что обнаруженные проблемы, такие как #6173, показали, что диалекты, которые жестко кодируют литеральные значения из скомпилированного оператора, часто числовые параметры, используемые для LIMIT / OFFSET, не будут совместимы с кэшированием, пока эти диалекты не будут пересмотрены для использования параметров, присутствующих только в операторе. Для сторонних диалектов, в которых этот флаг не применяется, в журнале SQL будет отображаться сообщение «диалект не поддерживает кэширование», указывающее на то, что диалект должен попытаться применить этот флаг после того, как убедится, что на этапе компиляции не передаются буквенные значения из каждого утверждения.References: #6184
schema¶
Введен новый параметр
Enum.omit_aliases
в типеEnum
, позволяющий фильтровать псевдонимы при использовании pep435 Enum. Предыдущие версии SQLAlchemy сохраняли псевдонимы во всех случаях, создавая в базе данных тип enum с дополнительными состояниями, что означало, что в db они трактовались как разные значения. Для обратной совместимости этот флаг по умолчанию имеет значениеFalse
в серии 1.4, но будет переключен наTrue
в одной из будущих версий. Если этот флаг не указан, а переданное перечисление содержит псевдонимы, то будет выдано предупреждение об устаревании.References: #6146
mypy¶
Исправлена проблема в плагине mypy, когда вновь добавленная поддержка
as_declarative()
требовала более полного добавления классаDeclarativeMeta
в состояние интерпретатора mypy, чтобы это не приводило к ошибке name not found; дополнительно улучшена настройка глобальных имен для плагина, включая имяMapped
.References: #sqlalchemy/sqlalchemy2-stubs/#14
asyncio¶
Исправлена проблема, при которой расширение asyncio не могло быть загружено при использовании Python 3.6 с установленной библиотекой backport
contextvars
.References: #6166
postgresql¶
Исправлена регрессия, вызванная #6023, когда оператор приведения PostgreSQL, применяемый к элементам внутри
ARRAY
при использовании psycopg2, не мог использовать правильный тип в случае, если тип данных также был встроен в экземпляр адаптераVariant
.Кроме того, исправлена поддержка корректной выдачи CREATE TYPE при использовании
Variant(ARRAY(some_schema_type))
.This change is also backported to: 1.3.25
References: #6182
Исправлена опечатка в исправлении для #6099, выпущенном в версии 1.4.4, которая полностью исключала корректную работу этого изменения, т.е. сообщение об ошибке не соответствовало тому, что на самом деле выдавалось pg8000.
References: #6099
Исправлена проблема, из-за которой при генерации PostgreSQL
PGInspector
на основеEngine
происходил сбой для.get_enums()
,.get_view_names()
,.get_foreign_table_names()
и.get_table_oid()
, когда они использовались не непосредственно с соединением, а с движком в стиле «future».References: #6170
mysql¶
Исправлена регрессия в диалекте MySQL, когда запрос на отражение, используемый для определения существования таблицы, давал сбой на очень старых версиях MySQL 5.0 и 5.1.
References: #6163
mssql¶
В MSSQL 2012+ исправлена ошибка, из-за которой не выводилось предложение order by при использовании
offset=0
в подзапросе.References: #6163
oracle¶
Исправлена критическая ошибка, при которой компилятор Oracle не сохранял правильные значения параметров в LIMIT/OFFSET для select из-за проблемы с кэшированием.
References: #6173
1.4.4¶
Released: March 30, 2021orm¶
Исправлена критическая проблема в новой функции
PropComparator.and_()
, когда стратегии загрузчика, выдающие вторичные операторы SELECT, такие какselectinload()
иlazyload()
, не учитывали связанные параметры в пользовательских критериях с точки зрения текущего выполняемого оператора, а не кэшируемого оператора, что приводило к использованию устаревших связанных значений.Это также добавляет предупреждение для случая, когда объект, использующий
lazyload()
в сочетании сPropComparator.and_()
, пытается быть сериализованным; критерии загрузчика не могут быть надежно сериализованы и десериализованы, и для этого случая должна быть использована ускоренная загрузка.References: #6139
Исправлено отсутствие метода
Session.get()
из интерфейсаScopedSession
.References: #6144
engine¶
Модифицирован менеджер контекста, используемый
Transaction
, таким образом, что предупреждение «уже отсоединен» не выдается при завершении самого менеджера контекста, если транзакция уже была откачена вручную внутри блока. Это относится и к обычным транзакциям, и к транзакциям с точкой сохранения, и к унаследованным «маркерным» транзакциям. Предупреждение все равно выдается, если метод.rollback()
вызывается явно более одного раза.References: #6155
Исправление неверных аргументов метода обработки исключений в CursorResult.
References: #6138
postgresql¶
Исправлена проблема в отражении PostgreSQL, когда столбец, выражающий «NOT NULL», заменял собой нулевость соответствующего домена.
This change is also backported to: 1.3.24
References: #6161
Изменен обработчик
is_disconnect()
для диалекта pg8000, который теперь учитывает новыйInterfaceError
, появившийся в pg8000 1.19.0. Pull request любезно предоставлен Хамди Бураком Усулом.References: #6099
misc¶
Скорректировано использование библиотеки
importlib_metadata
для загрузки точек входа setuptools с учетом некоторых изменений в устаревании.
1.4.3¶
Released: March 25, 2021orm¶
Исправлена ошибка, при которой python 2.7.5 (по умолчанию на CentOS 7) не мог импортировать sqlalchemy, поскольку на этой версии Python функции
exec "statement"
иexec("statement")
ведут себя по-разному. Вместо этого была использована совместимая функцияexec_()
.References: #6069
Исправлена ошибка, при которой ORM-запросы, использующие коррелированный подзапрос в сочетании с
column_property()
, не коррелировали корректно с вложенным подзапросом или CTE, если в свойстве для управления корреляцией использовалосьSelect.correlate_except()
, в случаях, когда подзапрос содержал те же selectables, что и в коррелированном подзапросе, которые не должны были коррелировать.References: #6060
Исправлена ошибка, из-за которой комбинации новой функции «отношения с критериями» могли не работать в сочетании с функциями, использующими новую функцию «лямбда SQL», включая такие стратегии загрузчика, как selectinload и lazyload, для более сложных сценариев, таких как полиморфная загрузка.
References: #6131
Исправлена поддержка корректной работы метода
ClauseElement.params()
с объектомSelect
, включающим соединения по структурам отношений ORM, что является новой возможностью в 1.4.References: #6124
Исправлена проблема, при которой предупреждение «удалено в 2.0» генерировалось внутренними средствами механики загрузчика отношений.
References: #6115
orm declarative¶
engine¶
Вернул имя
ResultProxy
обратно в пространство именsqlalchemy.engine
. Это имя относится к объектуLegacyCursorResult
.References: #6119
schema¶
Скорректирована логика выдачи операторов DROP для объектов
Sequence
при сбросе нескольких таблиц таким образом, что все объектыSequence
сбрасываются после всех таблиц, даже если данныйSequence
связан только с объектомTable
, а не непосредственно с общим объектомMetaData
. В данном случае поддерживается возможность одновременного связывания одного и того жеSequence
с несколькимиTable
.This change is also backported to: 1.3.24
References: #6071
mypy¶
Добавлена поддержка расширения Mypy для корректной интерпретации декларативного базового класса, сгенерированного с использованием функции
as_declarative()
, а также методаregistry.as_declarative_base()
.Исправлена ошибка в плагине Mypy, при которой определение типа столбца
Boolean
в Python приводило к исключению; дополнительно реализована поддержкаEnum
, включая определение строкового перечисления по сравнению с использованием Pythonenum.Enum
.References: #6109
postgresql¶
Настроен диалект psycopg2 на явное приведение в стиле PostgreSQL для связанных параметров, содержащих элементы ARRAY. Это позволяет корректно использовать весь спектр типов данных в массивах. Диалект asyncpg уже генерировал эти внутренние касты в финальном операторе. Также реализована поддержка обновления срезов массива и специфического для PostgreSQL метода
ARRAY.contains()
.This change is also backported to: 1.3.24
References: #6023
Исправлено отражение столбцов идентификации в таблицах с именами в смешанном регистре в PostgreSQL.
References: #6129
sqlite¶
Добавлена поддержка драйвера базы данных aiosqlite для использования с расширением SQLAlchemy asyncio.
См.также
References: #5920
Исправлен диалект
pysqlcipher
для корректного подключения, регрессировавший в 1.4, и добавлена поддержка тестирования + CI для поддержания драйвера в рабочем состоянии. Теперь диалект по умолчанию импортирует модульsqlcipher3
для Python 3, а затем возвращается кpysqlcipher3
, который документирован как не поддерживаемый.См.также
References: #5848
1.4.2¶
Released: March 19, 2021orm¶
Добавлена поддержка работы объекта
declared_attr
в контексте полей класса данных.References: #6100
Исправлена проблема в новой функциональности ORM dataclasses, когда поля dataclass на абстрактной базе или mixin, содержащие колонки или другие конструкции отображения, не отображались, если они также включали ключ «по умолчанию» в объекте dataclasses.field().
References: #6093
Исправлена регрессия, при которой удалялся аксессор
Query.selectable
, являющийся синонимомQuery.__clause_element__()
, теперь он восстановлен.References: #6088
Исправлена ошибка, при которой использование неименованного SQL-выражения, например, SQL-функции, приводило к ошибке нацеливания на столбец, если сам запрос использовал joinload для сущности, а также был обернут в подзапрос процессом ускоренной загрузки joinedload.
References: #6086
Исправлена ошибка, при которой метод
Query.filter_by()
не находил правильную исходную сущность, если методQuery.join()
использовался для сущности, не содержащей какой-либо ON-клаузулы.References: #6092
Исправлена регрессия, при которой SQL-компиляция
Function
работала некорректно, если объект был «аннотирован», что является внутренним процессом мемоизации, используемым в основном в ORM. В частности, это могло повлиять на «ленивую» загрузку ORM, которая в 1.4 стала более активно использовать эту возможность.References: #6095
Исправлена регрессия, при которой объединение
ConcreteBase
вообще не сопоставляло столбцы, когда имя сопоставляемого столбца совпадало с именем столбца-дискриминатора, выдавая ошибку утверждения. В версии 1.3 данный пример не работал корректно, поскольку полиморфное объединение приводило к запросу, который полностью игнорировал столбец-дискриминатор, выдавая при этом предупреждения о дублировании столбцов. Так как архитектура 1.4 не позволяет воспроизвести на уровнеselect()
это по сути неработающее поведение 1.3, то в данном случае выдается информативное сообщение об ошибке, в котором пользователю предлагается использовать атрибут.ConcreteBase._concrete_discriminator_name
для разрешения конфликта. Для облегчения этой настройки атрибут.ConcreteBase._concrete_discriminator_name
может быть помещен в базовый класс только там, где он будет автоматически использоваться подклассами; ранее это было не так.References: #6090
engine¶
sql¶
Исправлена проблема, при которой использование
func
, включающего точечные имена пакетов, не кэшировалось системой кэширования SQL из-за того, что список имен в Python должен был представлять собой кортеж.References: #6101
Исправлена регрессия в конструкции
case()
, при которой «словарная» форма указания аргумента не работала корректно, если он передавался позиционно, а не как аргумент с ключевым словом «whens».References: #6097
mypy¶
Исправлена проблема в расширении MyPy, при которой происходило падение при определении типа
Column
, если тип задавался с префиксом модуля, напримерsa.Integer()
.References: #sqlalchemy/sqlalchemy2-stubs/2
postgresql¶
Переименование имени столбца, используемого в запросе на отражение, в котором в некоторых базах данных, совместимых с postgresql, использовалось зарезервированное слово.
References: #6982
1.4.1¶
Released: March 17, 2021orm¶
Исправлена ошибка, когда при создании конструкции выражения Core, такой как
select()
, с использованием сущностей ORM происходило нетерпеливое конфигурирование мапперов, в попытке сохранить совместимость с объектомQuery
, который обязательно это делает для поддержки многих унаследованных случаев, связанных с backref. Однако конструкции ядраselect()
также используются в конфигурациях мапперов и т.п., и в этой степени такое ускоренное конфигурирование является скорее неудобством, поэтому ускоренное конфигурирование было отключено дляselect()
и других конструкций ядра в отсутствие функций загрузки ORM, таких какLoad
.Это изменение сохраняет поведение
Query
, что обеспечивает обратную совместимость. Однако при использованииselect()
в сочетании с сущностями ORM «обратная ссылка», которая не была явно помещена на один из классов до момента конфигурирования картографа, будет недоступна, если толькоconfigure_mappers()
или более новаяconfigure()
не была вызвана в другом месте. Предпочтительнее использоватьrelationship.back_populates
для более явной конфигурации отношений, которая не требует нетерпеливого конфигурирования.References: #6066
Исправлена критическая ошибка в ленивом загрузчике отношений, когда SQL-критерий, используемый для получения связанного объекта «многие-к-одному», мог стать устаревшим по отношению к другим мемоизированным структурам в загрузчике, если у мэппера изменялась конфигурация, что может произойти при несвоевременной настройке мэппера или настройке по требованию, что приводило к сравнению с None и возвращению отсутствия объекта. Огромная благодарность Алану Хамлетту (Alan Hamlett) за помощь в поиске этой проблемы глубокой ночью.
References: #6055
Исправлена ошибка, при которой метод
Query.exists()
не создавал выражение, если список сущностейQuery
представлял собой выражение произвольного SQL-столбца.References: #6076
Исправлена регрессия, при которой вызов метода
Query.count()
в сочетании с опцией загрузчика, напримерjoinedload()
, не позволял игнорировать опцию загрузчика. Такое поведение всегда было характерно для методаQuery.count()
; обычно ошибка возникает, если данныйQuery
имеет опции, которые не относятся к тому, что он возвращает.References: #6052
Исправлена регрессия в
Session.identity_key()
, заключающаяся в том, что метод и связанные с ним методы не были охвачены ни одним юнит-тестом, а также в том, что метод содержал опечатку, мешающую его корректной работе.References: #6067
orm declarative¶
Исправлена ошибка, из-за которой пользовательские классы, содержащие атрибут «registry», при использовании
DeclarativeMeta
вызывали конфликты с новой системой отображения на основе реестра. Хотя атрибут по-прежнему может быть явно задан в декларативной базе для использования метаклассом, после размещения он помещается в приватную переменную класса, чтобы не конфликтовать с будущими подклассами, использующими то же имя для других целей.References: #6054
engine¶
Python
namedtuple()
имеет такое поведение, что именаcount
иindex
будут обслуживаться как значения кортежа, если именованный кортеж включает эти имена; если же они отсутствуют, то сохраняется их поведение как методовcollections.abc.Sequence
. Поэтому классыRow
иLegacyRow
были исправлены таким образом, чтобы они работали аналогичным образом, сохраняя ожидаемое поведение для строк базы данных, имеющих столбцы с именами «index» или «count».References: #6074
mssql¶
Исправлена регрессия, при которой включался новый API setinputsizes(), доступный для pyodbc, который, очевидно, несовместим с режимом pyodbc fast_executemany() при отсутствии более точной информации о типизации, что пока не реализовано и не протестировано. Диалект и коннектор pyodbc были модифицированы таким образом, что функция setinputsizes() не используется вообще, если в диалект не передан параметр
use_setinputsizes
, например, черезcreate_engine()
, и тогда ее поведение может быть настроено с помощью хукаDialectEvents.do_setinputsizes()
.См.также
References: #6058
misc¶
В класс
ColumnCollection
вернулисьitems
иvalues
. Регрессия была внесена при добавлении поддержки дублирующихся столбцов в предложениях from и selectable в тикете #4753.References: #6068
1.4.0¶
Released: March 15, 2021orm¶
Удалено очень старое предупреждение о том, что параметр passive_deletes не предназначен для отношений «многие-к-одному». Хотя, вероятно, во многих случаях размещение этого параметра в отношениях «многие-к-одному» не является тем, что было задумано, существуют случаи, когда каскадное удаление может быть запрещено после таких отношений.
This change is also backported to: 1.3.24
References: #5983
Исправлена проблема, при которой процесс объединения двух таблиц мог завершиться неудачей, если одна из таблиц имела несвязанное, неразрешимое ограничение внешнего ключа, которое вызывало в процессе объединения исключение
NoReferenceError
, которое, тем не менее, можно было обойти, чтобы завершить объединение. Логика, проверяющая значимость исключения в процессе, сделала бы предположения о конструкции, которая бы дала сбой.This change is also backported to: 1.3.24
References: #5952
Исправлена проблема, при которой конструкция
MutableComposite
могла быть переведена в недопустимое состояние, когда родительский объект уже был загружен, а затем покрыт последующим запросом, из-за того, что обработчик обновления составных свойств заменял объект на новый, не обработанный мутабельным расширением.This change is also backported to: 1.3.24
References: #6001
Исправлена регрессия, при которой параметр
relationship.query_class
переставал работать для «динамических» отношений. ПараметрAppenderQuery
по-прежнему зависит от унаследованного классаQuery
; пользователям рекомендуется перейти от использования «динамических» отношений к использованию вместо нихwith_parent()
.References: #5981
Исправлена регрессия, при которой запрос
Query.join()
не давал эффекта, если сам запрос и цель присоединения были направлены на объектTable
, а не на сопоставленный класс. Это было частью более системной проблемы, когда старый компилятор ORM-запросов не мог корректно использоваться изQuery
, если в создаваемом операторе не было ORM-сущностей.References: #6003
API для
AsyncSession.delete()
теперь является ожидаемым; этот метод каскадирует отношения, которые должны быть загружены аналогично методуAsyncSession.merge()
.References: #5998
Теперь процесс unit of work полностью отключает поведение «lazy=“raise“», когда выполняется промывка. Хотя есть области, где UOW иногда загружает то, что в конечном итоге не нужно, стратегия «lazy=»raise»» здесь не поможет, поскольку пользователь часто не имеет достаточного контроля или видимости процесса промывки.
References: #5984
engine¶
Исправлена ошибка, при которой функция «schema_translate_map» не учитывалась для случая прямого выполнения объектов
DefaultGenerator
, таких как последовательности, что включало случай, когда они «предварительно выполнялись» для генерации значений первичных ключей при отключенном implicit_returning.This change is also backported to: 1.3.24
References: #5929
Улучшено протоколирование движка, чтобы отметить ROLLBACK и COMMIT, которые протоколируются, когда драйвер DBAPI находится в режиме AUTOCOMMIT. Эти ROLLBACK/COMMIT относятся к уровню библиотеки и не оказывают никакого влияния при работе в режиме AUTOCOMMIT, однако их все равно стоит регистрировать, поскольку они показывают, где SQLAlchemy видит разграничение «транзакций».
References: #6002
Исправлена ошибка, при которой «агент сброса» пула соединений не использовался
Connection
при его закрытии, а также приводил к сценарию двойного отката, что было несколько расточительно. В новой архитектуре движка логика «сброса при возврате» пула соединений была обновлена таким образом, чтобы она пропускалась, когдаConnection
явно закрывает транзакцию перед возвратом пула в соединение.References: #6004
sql¶
Изменена компиляция конструкции
CTE
, в результате чего возвращается строка, представляющая внутренний оператор SELECT, еслиCTE
строится непосредственно, вне контекста вложенного SELECT; такое же поведение характерно дляFromClause.alias()
иSelect.subquery()
. Ранее возвращалась пустая строка, поскольку CTE обычно размещается над SELECT после того, как этот SELECT уже сгенерирован, что, как правило, вводит в заблуждение при отладке.Исправлена ошибка, при которой для пользовательских операторов, использующих знаки процента, не включалась функция «экранирования процентов», возникающая в диалектах, использующих связанные стили параметров «format» или «pyformat», для конструкций
Operators.op()
иcustom_op
. Теперь знак процента будет автоматически удваиваться в зависимости от стиля параметра.References: #6016
Исправлена ошибка, при которой некорректно выдавалась ошибка «неподдерживаемая ошибка компиляции» для неизвестных типов данных.
References: #5979
Исправлена ошибка, при которой использование standalone
distinct()
в виде прямого SELECT’а приводило к невозможности размещения в наборе результатов по идентичности столбцов, что является способом размещения столбцов в ORM. Хотя автономное выражениеdistinct()
не ориентировано на непосредственный SELECT (используйтеselect.distinct()
для обычногоSELECT DISTINCT..
), ранее оно в ограниченной степени могло использоваться таким образом (но не работало, например, в подзапросах). В настоящее время улучшена адресация столбцов для унарных выражений типа «DISTINCT <col>», так что этот случай снова работает, а также сделано дополнительное улучшение, чтобы использование этой формы в подзапросе, по крайней мере, генерировало корректный SQL, чего раньше не происходило.Данное изменение дополнительно расширяет возможности целевого использования элементов в
row._mapping
на основе объектов SQL-выражений в операторах SELECT с поддержкой ORM, включая то, был ли оператор вызван с помощьюconnection.execute()
илиsession.execute()
.References: #6008
schema¶
Исправлена проблема, при которой ограничение CHECK, сгенерированное с помощью
Boolean
илиEnum
, после первой компиляции не могло корректно отобразить соглашение об именовании из-за непреднамеренного изменения состояния в имени, заданном ограничению. Впервые эта проблема была обнаружена в 0.9 в исправлении проблемы #3067, и данное исправление пересматривает принятый в то время подход, который, как оказалось, был более сложным, чем требовалось.This change is also backported to: 1.3.24
References: #6007
Исправлена / реализована поддержка соглашений об именовании ограничений первичного ключа, использующих имена столбцов/ключей/etc в качестве части соглашения. В частности, это включает в себя то, что объект
PrimaryKeyConstraint
, автоматически связанный сTable
, будет обновлять свое имя по мере добавления новых объектов первичного ключаColumn
в таблицу, а затем и в ограничение. Теперь учитываются внутренние режимы отказов, связанные с процессом построения ограничений, включая отсутствие столбцов, отсутствие имени или наличие пустого имени.This change is also backported to: 1.3.24
References: #5919
Утратили актуальность все методы уровня схемы
.copy()
и переименованы в_copy()
. Это не стандартные методы Python «copy()», так как они обычно полагаются на инстанцирование в определенных контекстах, которые передаются методу в качестве необязательных аргументов-ключей. МетодTable.tometadata()
является публичным API, обеспечивающим копирование для объектовTable
.References: #5953
mypy¶
Рудиментарная и экспериментальная поддержка Mypy была добавлена в виде нового плагина, который сам зависит от новых заглушек типизации для SQLAlchemy. Плагин позволяет декларативным отображениям в их стандартной форме быть совместимыми с Mypy, а также обеспечивать поддержку типизации для отображаемых классов и экземпляров.
References: #4609
postgresql¶
Для диалектов asyncpg и aiomysql в область видимости методов
cursor.execute()
иcursor.executemany()
добавленasyncio.Lock()
внутри эмулируемого SQLAlchemy курсора DBAPI, локального для соединения. Это сделано для того, чтобы предотвратить сбои и повреждения в случае, когда соединение используется сразу в нескольких awaitables.Хотя такой вариант использования может иметь место и в потоковом коде, и в диалектах, отличных от asyncio, мы ожидаем, что подобное использование будет более распространенным в asyncio, поскольку API asyncio поощряет такое использование. Однако, безусловно, лучше использовать отдельное соединение для каждого параллельного ожидаемого, поскольку в противном случае параллелизм не будет достигнут.
Для диалекта asyncpg это делается для того, чтобы пространство между вызовами
prepare()
иfetch()
не позволяло одновременному выполнению на соединении вызывать исключения интерфейсных ошибок, а также для предотвращения условий гонки при запуске новой транзакции. Другие PostgreSQL DBAPI являются потокобезопасными на уровне соединения, поэтому данная функция призвана обеспечить аналогичное поведение, не относящееся к курсорам на стороне сервера.Для диалекта aiomysql мьютекс обеспечивает безопасность, благодаря которой выполнение оператора и выборка набора результатов, являющиеся двумя разными этапами на уровне соединения, не будут нарушены одновременным выполнением на одном и том же соединении.
References: #5967
Исправлена проблема, при которой использование
aggregate_order_by
при определенных условиях возвращало ARRAY(NullType), что мешало объекту result корректно возвращать данные.This change is also backported to: 1.3.24
References: #5989
mssql¶
Исправление ошибки отражения для MSSQL 2005, связанной с отражением отфильтрованных индексов.
References: #5919
misc¶
Добавить новый параметр
AutomapBase.prepare.reflection_options
, позволяющий передавать опцииMetaData.reflect()
, такие какonly
, или специфические для диалекта опции отражения, такие какoracle_resolve_synonyms
.References: #5942
Расширение
sqlalchemy.ext.mutable
теперь отслеживает коллекцию «родителей» с помощьюInstanceState
, связанных с объектами, а не самого объекта. Последний подход требовал, чтобы объект был хэшируемым, чтобы он мог находиться внутриWeakKeyDictionary
, что противоречит поведенческому контракту ORM в целом, согласно которому отображаемые в ORM объекты не должны предоставлять какой-либо конкретный метод__hash__()
и что поддерживаются нехэшируемые объекты.References: #6020
1.4.0b3¶
Released: February 15, 2021orm¶
ORM, используемая в 2.0 style, теперь может возвращать ORM-объекты из строк, возвращаемых операторами UPDATE..RETURNING или INSERT..RETURNING, предоставляя конструкцию
Select.from_statement()
в ORM-контексте.В новых ORM-запросах в стиле 1.4/2.0 исправлена проблема, при которой стиль метки на уровне оператора не сохранялся в ключах, используемых в строках результатов; это было сделано для всех комбинаций столбцов Core/ORM / сессия vs. соединение и т.д., чтобы связь между оператором и строкой результатов была одинаковой во всех случаях. В рамках этого изменения была улучшена маркировка выражений столбцов в строках, чтобы сохранить оригинальное имя ORM-атрибута, даже если он используется в подзапросе.
References: #5933
engine¶
Продолжено улучшение, сделанное в рамках #5653 для дальнейшей поддержки связанных имен параметров, в том числе генерируемых по именам колонок, для имен, включающих двоеточия, круглые скобки и знаки вопроса, а также улучшена поддержка тестов, так что связанные имена параметров, даже если они автоматически выводятся из имен колонок, не должны иметь проблем с включением скобок в стиле «pyformat» psycopg2.
В рамках этого изменения формат, используемый адаптером asyncpg DBAPI (который является локальным для диалекта asyncpg SQLAlchemy), был изменен с парамстиля «qmark» на «format», поскольку существует стандартный и внутренне поддерживаемый стиль экранирования строк SQL для имен, использующих знаки процента со стилем «format» (т.е. для двойных знаков процента), в отличие от имен, использующих знаки вопроса со стилем «qmark» (где система экранирования не определена pep-249 или Python).
References: #5941
sql¶
Усовершенствовать ключевое слово
set_
изOnConflictDoUpdate
для приемаColumnCollection
, например, коллекции.c.
изSelectable
или контекстного объекта.excluded
.References: #5939
Исправлена ошибка, при которой утверждение о «картезианском произведении» некорректно учитывало соединения между таблицами, основанные на использовании LATERAL для перехода от подзапроса к другому подзапросу во вложенном контексте.
References: #5924
Исправлена регрессия 1.4, при которой метод
Function.in_()
не был охвачен тестами и не работал корректно во всех случаях.References: #5934
Исправлена регрессия, при которой использование произвольного итерируемого объекта с функцией
select()
не работало, за исключением простых списков. Логика совместимости вперед/назад здесь теперь проверяет более широкий диапазон входящих типов «iterable», включая возможность прямой передачи коллекции.c
из selectable. Pull request compliments of Oliver Rice.References: #5935
1.4.0b2¶
Released: February 3, 2021general¶
Исправлена ситуация, когда в исходном файле SQLite в строке docstring без кодировки исходного текста присутствовали символы, отличные от латиницы, введенные в функции «INSERT..ON CONFLICT», что приводило к сбоям под Python 2.
platform¶
Скорректированы некоторые элементы, связанные с внутренним производством классов при импорте, которые вносили значительные задержки во время импорта библиотеки по сравнению с 1.3. Теперь это время не 200%, а примерно 20-30% медленнее, чем в 1.3.
References: #5681
orm¶
В объект события
ORMExecuteState
добавлены аксессорыORMExecuteState.bind_mapper
иORMExecuteState.all_mappers
, чтобы обработчики могли реагировать на целевой mapper и/или mapped класс или классы, участвующие в выполнении оператора ORM.Добавлены
AsyncSession.scalar()
,AsyncSession.get()
, а также поддержкаsessionmaker.begin()
для работы в качестве асинхронного менеджера контекста сAsyncSession
. Также добавлен аксессорAsyncSession.in_transaction()
.Конфигурирование отображателя, которое происходит в функции
configure_mappers()
, теперь организовано на основе каждого реестра. Это позволяет, например, сконфигурировать отображатели определенной декларативной базы, но не отображатели другой базы, которая также присутствует в памяти. Цель состоит в том, чтобы сократить время запуска приложения, выполняя процесс «configure» только для тех наборов отображателей, которые необходимы. Сюда же добавляется методregistry.configure()
, который запускает configure только для мапперов, локализованных в определенном реестре.References: #5897
Добавлена комплексная проверка и информативное сообщение об ошибке для случая, когда в
relationship.secondary
передается сопоставленный класс или строковое имя сопоставленного класса. Это очень распространенная ошибка, которая требует четкого сообщения.Кроме того, добавлено новое правило для разрешения реестра классов, согласно которому для параметра
relationship.secondary
, если сопоставленный класс и его таблица имеют одинаковое строковое имя, то при разрешении этого параметра предпочтение будет отдаватьсяTable
. Во всех остальных случаях предпочтение по-прежнему отдается классу, если класс и таблица имеют одинаковое имя.This change is also backported to: 1.3.21
References: #5774
Исправлена ошибка, связанная с тем, что флаг
restore_load_context
в событиях ORM, таких какInstanceEvents.load()
, не переносился на подклассы, которые были отображены после создания обработчика события.This change is also backported to: 1.3.21
References: #5737
Исправлена проблема в новом
Session
, аналогичная той, что была вConnection
, когда новая логика «автозапуска» могла быть переведена в реентерабельное (рекурсивное) состояние, если SQL выполнялся внутри крючка событияSessionEvents.after_transaction_create()
.References: #5845
Улучшена система топологической сортировки единиц работы, в результате чего топологическая сортировка теперь детерминирована на основе сортировки входного набора, который сам сортируется на уровне картографов, так что одинаковые входы затронутых картографов должны давать одинаковый выход каждый раз, среди картографов/таблиц, не имеющих зависимости друг от друга. Это еще больше снижает вероятность возникновения тупиковых ситуаций, как это можно наблюдать при флеше, когда UPDATE выполняется в нескольких несвязанных таблицах, что приводит к возникновению блокировок строк.
References: #5735
Исправлена регрессия, при которой флаг
Bundle.single_entity
вступал в силу дляBundle
, даже если он не был установлен. Кроме того, этот флаг является устаревшим, так как имеет смысл только для объектаQuery
, а не для исполнения в стиле 2.0. При его использовании с исполнением в новом стиле выдается предупреждение об устаревании.References: #5702
Исправлена ошибка, при которой создание конструкции
aliased
против обычного selectable и включение в нее имени приводило к возникновению ошибки утверждения.References: #5750
В связи с исправлениями системы лямбда-критериев в Core, в ORM реализован ряд исправлений для функции
with_loader_criteria()
, а также обработчика событияSessionEvents.do_orm_execute()
, который часто используется совместно [ticket:5760]:Исправлена проблема, при которой функция
with_loader_criteria()
не выполнялась, если заданная сущность или база включала в свою нисходящую иерархию классов не отображаемые миксины [ticket:5766].Функция
with_loader_criteria()
теперь безоговорочно отключена для операций «обновления» ORM, включая загрузку отложенных или просроченных атрибутов столбцов, а также для явных операций типаSession.refresh()
. Такие загрузки обязательно основаны на идентичности первичного ключа, где дополнительные критерии WHERE никогда не бывают уместны. [ticket:5762]Добавлен новый атрибут
ORMExecuteState.is_column_load
для указания обработчикуSessionEvents.do_orm_execute()
, что данная операция является загрузкой атрибутов столбцов, ориентированной на первичный ключ, где дополнительные критерии добавлять не следует. Функцияwith_loader_criteria()
, как указано выше, в любом случае их игнорирует. [ticket:5761]Исправлена проблема, при которой атрибут
ORMExecuteState.is_relationship_load
не устанавливался корректно для многих ленивых загрузок, а также для всех селективных загрузок. Флаг необходим для проверки того, нужно ли добавлять опции в операторы, или они уже были переданы с помощью загрузки отношений. [ticket:5764]
Исправлена регрессия 1.4, при которой использование
Query.having()
в запросах с внутренне адаптированными элементами SQL (часто встречающееся в сценариях наследования) приводило к ошибке из-за некорректного вызова функции. Pull request courtesy esoh.References: #5781
Исправлена проблема, при которой API для создания пользовательской исполняемой SQL-конструкции с использованием расширения
sqlalchemy.ext.compiles
в соответствии с документацией, которая существует уже много лет, переставал работать, если в качестве базовых классов использовались толькоExecutable, ClauseElement
, а для использованияSession.execute()
требовались дополнительные классы. Эта проблема была решена, так что дополнительные классы больше не нужны.Исправлена ошибка в работе ORM, когда ошибочный оператор «assert primary_key» мешал последовательностям генерации первичных ключей, которые не учитывали столбцы таблицы для использования реального ограничения первичного ключа, а вместо этого использовали
Mapper.primary_key
для определения некоторых столбцов как «первичных».References: #5867
orm declarative¶
В Declarative добавлена альтернативная схема разрешения, которая позволяет извлекать колонку SQLAlchemy или сопоставленное свойство из словаря «метаданных» объекта dataclasses.Field. Это позволяет комбинировать полные декларативные отображения с полями классов данных.
References: #5745
engine¶
Конструкции, специфичные для диалекта, такие как
Insert.on_conflict_do_update()
, теперь могут строчить на месте без необходимости указывать явный объект диалекта. Конструкции, вызываемые дляstr()
,print()
и т.д., теперь имеют внутреннее направление для вызова соответствующего диалекта, а не диалекта «по умолчанию», который не знает, как их строчить. Этот подход также адаптирован к общим схемам создания/удаления на уровне схемы, таким какAddConstraint
, которые будут адаптировать свой диалект структуризации к диалекту, указанному элементом внутри них, таким как объектExcludeConstraint
.Добавлена новая опция выполнения
Connection.execution_options.logging_token
. Эта опция добавляет дополнительный токен для каждого сообщения в сообщения журнала, генерируемыеConnection
при выполнении операторов. Этот маркер не является частью имени самого логгера (эта часть может быть изменена с помощью существующего параметраcreate_engine.logging_name
), поэтому он подходит для использования в специальных соединениях без побочного эффекта создания множества новых логгеров. Параметр может быть задан на уровнеConnection
илиEngine
.References: #5911
Исправлена ошибка в «будущей» версии 2.0
Engine
, когда выполнение SQL во время хука событияEngineEvents.begin()
приводило к реентерабельному (рекурсивному) состоянию из-за автозапуска, что, помимо прочего, влияло на рецепт, документированный для SQLite, чтобы обеспечить поддержку точек сохранения и сериализуемой изоляции.References: #5845
Логика «setinputsizes», используемая диалектами cx_Oracle, asyncpg и pg8000, скорректирована для поддержки
TypeDecorator
, включающего переопределение методаTypeDecorator.get_dbapi_type()
.В список слов, известных функции
engine_from_config()
, добавлено ключевое слово «future», благодаря чему значения «true» и «false» могут быть сконфигурированы как «булевы» значения при использовании ключей типаsqlalchemy.future = true
илиsqlalchemy.future = false
.
sql¶
Реализована поддержка «табличных функций», а также дополнительных синтаксисов, поддерживаемых PostgreSQL, что является одной из наиболее часто запрашиваемых возможностей. Табличные функции - это функции SQL, которые возвращают списки значений или строк, и распространены в PostgreSQL в области функций JSON, где «табличное значение» обычно называется типом данных «запись». Табличные функции также поддерживаются в Oracle и SQL Server.
Добавлены следующие функции:
модификатор
FunctionElement.table_valued()
, создающий из SQL-функции таблично-подобный выбираемый объектКонструкция
TableValuedAlias
, представляющая SQL-функцию в виде именованной таблицыПоддержка специального синтаксиса PostgreSQL «производный столбец», включающего имена столбцов, а иногда и типы данных, например, для функции
json_to_recordset
используется методTableValuedAlias.render_derived()
.Поддержка конструкции PostgreSQL «WITH ORDINALITY» с использованием параметра
FunctionElement.table_valued.with_ordinality
Поддержка выбора функции FROM SQL в качестве скаляра со значением столбца (синтаксис, поддерживаемый PostgreSQL и Oracle) с помощью метода
FunctionElement.column_valued()
.Способ выбора одного столбца из таблично-значного выражения без использования предложения FROM с помощью метода
FunctionElement.scalar_table_valued()
.
References: #3566
Несколько вызовов «возврата», например
Insert.returning()
, теперь могут быть соединены в цепочку для добавления новых столбцов в предложение RETURNING.References: #5695
Добавлен метод
Select.outerjoin_from()
, дополняющийSelect.join_from()
.Скорректирована функция «literal_binds» в
Compiler
, которая теперь выводит NULL для связанного параметра, имеющего в качестве значенияNone
, переданного явно или опущенного. Предыдущее сообщение об ошибке «bind parameter without a renderable value» удалено, а отсутствующее илиNone
значение теперь будет отображаться NULL во всех случаях. Ранее рендеринг NULL начинал происходить для операторов DML из-за внутренних рефакторингов, но не был явно включен в тестовое покрытие, а теперь стал.Хотя ошибка не возникает, когда контекст находится в пределах сравнения столбцов, а оператор не является «IS»/»IS NOT», выдается предупреждение о том, что это не является полезным с точки зрения SQL.
References: #5888
Исправлена проблема в новом методе
Select.join()
, когда цепочка из текущего JOIN не смотрела на правильное состояние, что приводило к выражению типа «FROM a JOIN b <onclause>, b JOIN c <onclause>», а не «FROM a JOIN b <onclause> JOIN c <onclause>».References: #5858
В режиме «SQLALCHEMY_WARN_20» при передаче простой строки в
Session.execute()
выдаются предупреждения об износе.References: #5754
На основе отзывов пользователей были внесены разнообразные исправления в функцию «лямбда SQL», представленную в Использование ламбдас для значительного увеличения скорости создания операторов, с акцентом на ее использование в рамках функции
with_loader_criteria()
, где она используется наиболее активно [ticket:5760]:Исправлена проблема, при которой булевые значения True/False, на которые ссылались закрывающие переменные лямбды, приводили к сбоям [ticket:5763].
Исправлено нерабочее определение для Python-функций, встроенных в лямбду и выдающих связанные значения; этот случай, скорее всего, не поддерживается, поэтому выдается информативная ошибка, при которой функция должна быть вызвана вне самой лямбды. Добавлена новая документация для более подробного описания этого поведения. [ticket:5770]
Теперь лямбда-система по умолчанию полностью отвергает использование не SQL-элементов в закрывающих переменных лямбды, при этом ошибка предлагает два варианта: либо явно игнорировать закрывающие переменные, не являющиеся SQL-параметрами, либо указать конкретный набор значений, которые будут рассматриваться в качестве части ключа кэша на основе хэш-значения. Это позволяет системе лямбд не считать, что произвольные объекты внутри закрытия лямбды подходят для кэширования, и в то же время отказаться от их игнорирования по умолчанию, предотвращая случаи, когда их состояние может быть непостоянным и оказывать влияние на создаваемую SQL-конструкцию. Сообщение об ошибке является исчерпывающим, и добавлена новая документация для более подробного описания этого поведения. [ticket:5765]
Исправлена поддержка граничного случая, когда выражение
in_()
против списка элементов SQL, например, объектовliteral()
, не может быть корректно размещено. [ticket:5768]
Для выбранного набора методов DML (в настоящее время все они являются частью конструкций
Insert
) теперь выдается информативное сообщение об ошибке, если они вызываются второй раз, что неявно отменяет предыдущую установку. К измененным методам относятся:on_conflict_do_update
,on_conflict_do_nothing
(SQLite),on_conflict_do_update
,on_conflict_do_nothing
(PostgreSQL),on_duplicate_key_update
(MySQL).References: #5169
Исправлена проблема в новой конструкции
Values
, когда при передаче кортежей объектов происходил откат к определению типа по значению, а не использование объектовColumn
, передаваемых непосредственно вValues
, что сообщало SQLAlchemy об ожидаемом типе. Это приведет к проблемам для таких объектов, как перечисления и строки numpy, которые на самом деле не нужны, поскольку ожидаемый тип указан.References: #5785
Исправлена проблема, когда при внутреннем обращении к объектам с атрибутом
RemovedIn20Warning
ошибочно выдавался.bind
, в частности, при структуризации SQL-конструкции.References: #5717
Правильно отображать
cycle=False
иorder=False
какNO CYCLE
иNO ORDER
в объектахSequence
иIdentity
.References: #5722
Замените
Query.with_labels()
иGenerativeSelect.apply_labels()
явными геттерами и сеттерамиGenerativeSelect.get_label_style()
иGenerativeSelect.set_label_style()
, чтобы учесть три поддерживаемых стиля меток:LABEL_STYLE_DISAMBIGUATE_ONLY
,LABEL_STYLE_TABLENAME_PLUS_COL
иLABEL_STYLE_NONE
.Кроме того, для Core и ORM-запросов «будущего стиля» теперь по умолчанию используется стиль меток
LABEL_STYLE_DISAMBIGUATE_ONLY
. Этот стиль отличается от существующего стиля «без меток» тем, что метка применяется в случае конфликта имен столбцов; при использованииLABEL_STYLE_NONE
дублирующееся имя столбца в любом случае недоступно по имени.Для случаев, когда маркировка имеет большое значение, а именно, чтобы коллекция
.c
подзапроса могла однозначно ссылаться на все столбцы, поведениеLABEL_STYLE_DISAMBIGUATE_ONLY
теперь является достаточным для всех функций SQLAlchemy в Core и ORM, которые предполагают такое поведение. Строки результирующего набора, начиная с SQLAlchemy 1.0, обычно выравниваются по столбцам позиционно.Для старых ORM-запросов, использующих
Query
, по-прежнему используется стиль маркировки таблиц плюс имена столбцов, применяемый вLABEL_STYLE_TABLENAME_PLUS_COL
, так что существующие наборы тестов и средства протоколирования по умолчанию не видят изменений в поведении.References: #4757
schema¶
Добавлена функция
TypeEngine.as_generic()
для сопоставления диалектных типов, таких какsqlalchemy.dialects.mysql.INTEGER
, с «наилучшим соответствием» общим типам SQLAlchemy, в данном случаеInteger
. Pull request любезно предоставлен Эндрю Ханниганом.См.также
Отражение с помощью типов, не зависящих от базы данных - пример использования
References: #5659
Теперь событие
DDLEvents.column_reflect()
может быть применено к объектуMetaData
, где оно будет действовать для объектовTable
, локальных для этой коллекции.См.также
Автоматизация схем именования столбцов из отраженных таблиц - в документации по отображению ORM
Определения перехватывающих колонок - в документации Automap
References: #5712
К конструкциям
CreateTable
,DropTable
,CreateIndex
иDropIndex
добавлены параметрыCreateTable.if_not_exists
,CreateIndex.if_not_exists
,DropTable.if_exists
иDropIndex.if_exists
, которые приводят к конструкциям «IF NOT EXISTS» / «IF EXISTS» DDL, которые добавляются к CREATE/DROP. Эти фразы принимаются не всеми базами данных, и операция завершится неудачей в базе данных, которая их не поддерживает, поскольку в рамках одного DDL-оператора нет аналогичного совместимого запасного варианта. Pull request любезно предоставлен Рамоном Уильямсом.References: #2843
Изменено поведение конструкции
Identity
таким образом, что при ее применении кColumn
автоматически подразумевается, что значениеColumn.nullable
по умолчанию должно быть равноFalse
, аналогично тому, как это происходит при установке параметраColumn.primary_key
в значениеTrue
. Это соответствует поведению по умолчанию всех поддерживающих баз данных, гдеIDENTITY
подразумеваетNOT NULL
. Бэкенд PostgreSQL является единственным, поддерживающим добавлениеNULL
к столбцуIDENTITY
, что здесь поддерживается одновременной передачей значенияTrue
для параметраColumn.nullable
.References: #5775
asyncio¶
Объекты
AsyncEngine
,AsyncConnection
иAsyncTransaction
можно сравнивать с помощью Python==
или!=
, которые будут сравнивать два заданных объекта на основе объекта «синхронизации», к которому они проксируются. Это полезно, так как, в частности, дляAsyncTransaction
, есть случаи, когда несколько экземпляровAsyncTransaction
могут быть проксированы на один и тот же синхронизаторTransaction
, а на самом деле являются эквивалентными. В настоящее время методAsyncConnection.get_transaction()
будет каждый раз возвращать новый проксирующийAsyncTransaction
, посколькуAsyncTransaction
не связан каким-либо иным образом по состоянию с породившим егоAsyncConnection
.Интеграция greenlet, обеспечивающая поддержку Python asyncio в SQLAlchemy, скорректирована с учетом обработки Python
contextvars
(появилась в Python 3.7) для версийgreenlet
, превышающих 0.4.17. В версии Greenlet 0.4.17 добавлена автоматическая обработка contextvars, не совместимая с предыдущей версией; мы согласовали с авторами greenlet добавление предпочтительного API для этого в версиях после 0.4.17, который теперь поддерживается интеграцией greenlet в SQLAlchemy. Для версий greenlet, предшествующих 0.4.17, никаких изменений в поведении не требуется, версия 0.4.17 сама блокируется из зависимостей.References: #5615
Реализовано «связывание соединений» для
AsyncSession
- возможность передачиAsyncConnection
для созданияAsyncSession
. Ранее эта возможность не была реализована и при передаче соединения использовался связанный движок. Это устраняет проблему, при которой сценарий «присоединение сеанса к внешней транзакции» не работал корректно дляAsyncSession
. Кроме того, добавлены методыAsyncConnection.in_transaction()
,AsyncConnection.in_nested_transaction()
,AsyncConnection.get_transaction()
,AsyncConnection.get_nested_transaction()
и атрибутAsyncConnection.info
.References: #5811
Исправлена ошибка в пуле подключений asyncio, когда вместо
TimeoutError
выдавалосьasyncio.TimeoutError
. Также исправлен параметрcreate_engine.pool_timeout
, установленный в ноль при использовании асинхронного механизма, который ранее игнорировал таймаут и блокировал, а не завершал работу сразу, как это происходит с обычнымQueuePool
.References: #5827
При использовании движка asyncio пул соединений теперь будет отсоединять и отбрасывать пул соединений, которые не были явно закрыты/возвращены в пул при сборке его объекта отслеживания, выдавая предупреждение о том, что соединение не было закрыто должным образом. Поскольку эта операция происходит во время финализаторов Python gc, небезопасно выполнять какие-либо операции ввода-вывода над соединением, включая откат транзакции или закрытие соединения, поскольку это часто происходит вне цикла событий.
AsyncAdaptedQueue
, используемый по умолчанию в async dpapis, должен инстанцировать очередь только при ее первом использовании, чтобы избежать ее привязки к возможному неправильному циклу событий.References: #5823
Режим async SQLAlchemy теперь обнаруживает и выдает информационную ошибку при использовании несовместимого с asyncio цикла DBAPI. Использование стандартного
DBAPI
в async SQLAlchemy приведет к его блокировке, как и любого другого синхронного вызова, прерывая выполняющийся asyncio цикл.
postgresql¶
В объект
ExcludeConstraint
добавлен новый параметрExcludeConstraint.ops
для поддержки спецификации класса оператора с этим ограничением. Pull request любезно предоставлен Alon Menczer.This change is also backported to: 1.3.21
References: #5604
В слой адаптации DBAPI для диалекта asyncpg добавлен атрибут чтения/записи
.autocommit
. Это сделано для того, чтобы при работе с DBAPI-специфичными схемами, в которых необходимо использовать «autocommit» непосредственно с DBAPI-соединением, был доступен тот же атрибут.autocommit
, который работает как с psycopg2, так и с pg8000.Исправлена проблема, при которой диалект psycopg2 молча передавал флаг
use_native_unicode=False
, не оказывая на него никакого влияния под Python 3, так как под Python 3 DBAPI psycopg2 безоговорочно использует Unicode. Теперь такое использование приводит к появлению флагаArgumentError
при использовании под Python 3. Добавлена тестовая поддержка для Python 2.Повышена производительность диалекта asyncpg за счет кэширования объектов asyncpg PreparedStatement на основе каждого соединения. Для тестового случая, использующего один и тот же запрос на множестве объединенных соединений, это дает прирост скорости на 10-20%. Размер кэша настраивается и может быть отключен.
См.также
Table
text()
Select.with_for_update.of
FThis change is also backported to: 1.3.21
References: #5729
Исправлена небольшая ошибка, при которой запрос «show standard_conforming_strings» при инициализации выдавался, даже если информация о версии сервера была меньше версии 8.2, ранее это происходило только для версии сервера 8.2 и выше. Запрос не выполняется на Amazon Redshift, который сообщает о версии сервера PG, превышающей это значение.
References: #5698
Column
set_
Insert.on_conflict_do_update()
Insert.on_conflict_do_update()
Column
.c
Table
EReferences: #5722
Исправлена ошибка в диалекте asyncpg, когда сбой во время «фиксации» или, что менее вероятно, «отката» должен был отменить всю транзакцию; теперь откат невозможен. Ранее соединение продолжало ожидать отката, который не мог быть успешным, так как asyncpg отвергал его.
References: #5824
mysql¶
Добавлена поддержка драйвера aiomysql при использовании расширения asyncio SQLAlchemy.
См.также
References: #5747
Исправлена проблема, при которой отражение значения по умолчанию сервера только для MariaDB, содержащего десятичную точку в значении, не отражалось корректно, что приводило к появлению отраженной таблицы, в которой отсутствовало значение по умолчанию сервера.
This change is also backported to: 1.3.21
References: #5744
sqlite¶
mssql¶
Comparator.as_float()
Comparator.as_numeric()
Decimal
DReferences: #5788
oracle¶
#5755
v$transaction
Connection.get_isolation_level()
FThis change is also backported to: 1.3.22
References: #5784
Двухфазные транзакции Oracle на рудиментарном уровне теперь не являются устаревшими. После получения поддержки от разработчиков cx_Oracle мы можем обеспечить базовую поддержку xid + begin/prepare с некоторыми ограничениями, которая будет работать более полно в ближайшем выпуске cx_Oracle. Двухфазное «восстановление» в настоящее время не поддерживается.
References: #5884
select sys_context( 'userenv', 'current_schema' ) from dual
SELECT USER FROM DUAL
TReferences: #5716
tests¶
Улучшена документация и добавлен тест на тайм-ауты пулов за несколько секунд. Pull request любезно предоставлен Jordan Pittier.
References: #5582
misc¶
PoolEvents.connect()
insert=True
T``autoload``F
References: #5684
``insert=True``F
References: #5708
Исправлена проблема, при которой пул соединений не возвращал соединения в пул или иным образом не завершал сборку мусора в pypy, если проверенное соединение выходило из области видимости, не будучи закрытым. Это давняя проблема, связанная с отличием поведения pypy в GC, который не вызывает финализаторы weakref, если они находятся относительно другого объекта, который также собирается в мусор. Теперь сохраняется сильная ссылка на связанную запись, чтобы у weakref была «база» с сильными ссылками для срабатывания.
References: #5842
1.4.0b1¶
Released: November 2, 2020general¶
»python setup.py test» больше не является программой запуска тестов, так как она устарела в Pypa. Для базового запуска тестов используйте команду «tox» без аргументов.
References: #4789
Рефакторинг внутренних соглашений, используемых при кросс-импорте модулей, имеющих взаимные зависимости между собой, заключается в том, что проверяемые аргументы функций и методов больше не изменяются. Это позволяет корректно работать таким инструментам, как pylint, Pycharm, другим редакторам кода, а также гипотетическим реализациям pep-484, добавляемым в будущем, поскольку они больше не видят недостающих аргументов в вызовах функций. Новый подход также является более простым и производительным.
platform¶
``importlib_metadata``T
References: #5400
Установка была модернизирована для использования setup.cfg для большинства метаданных пакета.
References: #5404
Прекращена поддержка python 3.4 и 3.5, достигших EOL. Для работы SQLAlchemy серии 1.4 требуется python 2.7 или 3.6+.
References: #5634
Удален весь диалектный код, связанный с поддержкой Jython и zxJDBC. Jython не поддерживается SQLAlchemy уже много лет, и не ожидается, что текущий код zxJDBC вообще функционален; на данный момент он просто занимает место и вносит путаницу, появляясь в документации. В настоящее время, судя по всему, Jython в своих релизах добился поддержки Python 2.7, но не Python 3. Если поддержка Jython будет возобновлена, то она должна быть реализована в виде поддержки версии Jython 3 для Python 3, а различные заглушки zxJDBC для различных бэкендов должны быть реализованы в виде диалекта сторонних разработчиков.
References: #5094
orm¶
Query
select()
Select
Query
Select
Update
Delete
Session.execute()
Select
Result
TReferences: #5159
-
References: #4472
sqlalchemy.orm
dataclasses
attrs
TСм.также
Декларативность теперь интегрирована в ORM с новыми возможностями
Поддерживаются классы данных и атрибуты Python с декларативными и императивными отображениями
References: #5508
Такие загрузчики, как joined loading, SELECT IN loading и т.д., при настройке на маппере или через опции запроса теперь будут вызываться при обновлении на истекшем объекте; в случае selectinload и subqueryload, поскольку дополнительная загрузка производится только для одного объекта, в этих случаях используется схема «immediateload», напоминающая однородительский запрос, выдаваемый при ленивой загрузке.
References: #1763
dataclasses
dataclasses
attrs
AСм.также
Поддерживаются классы данных и атрибуты Python с декларативными и императивными отображениями
Декларативность теперь интегрирована в ORM с новыми возможностями
References: #5027
defer.raiseload
defer()
deferred()
raiseload()
AСм.также
References: #4826
Оценщик, выполняющий в ORM массовое обновление и удаление для synchronize_session=»evaluate», теперь поддерживает операторы IN и NOT IN. Также поддерживается оператор IN для кортежей.
References: #1653
:paramref:`_orm.relationship.overlaps`E
References: #5171
Query.update()
Query.delete()
Update
Delete
2.0 stylewith_loader_criteria()
Trelationship.sync_backref
False
viewonly=True
UReferences: #5237
FlushError
IntegrityError
IntegrityError
TСм.также
Ошибка «Новый экземпляр конфликтует с существующей идентификацией» теперь является предупреждением
References: #4662
Некоторые объекты запросов Core и ORM теперь выполняют большую часть вычислительных задач Python на этапе компиляции, а не во время конструирования. Это сделано для поддержки будущей модели кэширования, которая предусматривает кэширование скомпилированной структуры оператора на основе ключа кэша, получаемого из конструкции оператора, который, как ожидается, будет заново создаваться в коде Python при каждом использовании. Это означает, что внутреннее состояние этих объектов может быть не таким, как раньше, а также то, что некоторые, но не все сценарии обнаружения ошибок при различных видах проверки аргументов будут возникать на этапе компиляции/исполнения, а не во время построения утверждения. Более подробная информация приведена в примечаниях по миграции, ссылки на которые приведены ниже.
2.0 style
Result.unique()
selectinload()
TReferences: #4395
select()
Query.select_entity_from()
Query.select_from()
with_polymorphic()
SelectBase
select()
Query
SelectBase.alias()
SelectBase.subquery()
TReferences: #4617
-
References: #4710
execute_values()
#5401execute_values()
IСм.также
ORM Пакетные вставки с psycopg2 теперь в большинстве случаев выполняют пакетные операции с RETURNING
References: #5263
Query.select_entity_from()
Query
AСм.также
Более строгое поведение при запросе отображений наследования с помощью пользовательских запросов
References: #5122
Внутренние символы атрибутов NO_VALUE и NEVER_SET были унифицированы, так как между ними не было существенной разницы, за исключением нескольких кодовых путей, где они различались тонким и недокументированным образом, что было исправлено.
References: #4696
-
References: #4194
UnmappedInstanceError
InstrumentedAttribute
AttributeError
AReferences: #3858
Session
SessionTransaction
SessionTransaction
Session
SessionTransaction
SessionEvents.after_transaction_create()
Session
SessionTransaction
Session
SessionTransaction
Engine
TReferences: #5074
Session
Query
Query.subquery()
select()
AReferences: #4829
ArgumentError
selectable
flat
with_polymorphic()
AReferences: #4212
Исправлена проблема во внутреннем устройстве полиморфной загрузки, которая при использовании «with_polymorphic» в некоторых сценариях неиспользования возвращалась к более дорогой и скоро устаревшей форме поиска столбцов результатов.
References: #4718
-
References: #4994
Улучшено сканирование декларативного наследования, чтобы не возникало ошибок при многократном появлении одного и того же базового класса в списке базового наследования.
References: #4699
Исправлена ошибка в функции версионности ORM, при которой присвоение явного version_id для счетчика, настроенного на отображаемый selectable, где version_id_col относится к базовой таблице, при истечении срока действия предыдущего значения приводило к неудаче; это было связано с тем, что отображаемый атрибут не был настроен с active_history=True.
References: #4195
Теперь возникает исключение, если ORM загружает строку для полиморфного экземпляра, имеющего первичный ключ, но столбец дискриминатора равен NULL, так как столбцы дискриминатора не должны быть нулевыми.
References: #4836
__dict__
None
__dict__
__dict__
AСм.также
Доступ к неинициализированному атрибуту коллекции на переходном объекте больше не мутирует __dict__.
References: #4519
Session.expire()
Session.refresh()
Session.expire.autoflush
Session.refresh.autoflush
TReferences: #5226
relationship.cascade_backrefs
False
True
False
relationship()
Session.future
TReferences: #5150
-
References: #5606
Query.instances()
QueryContext
Query
ResultProxy
QueryContext
Query.from_statement()
CReferences: #4719
Query.join()
selectinload()
of_type()
Ualiased
from_joinpoint
Query.join()
aliased()
A:meth:`_query.Query.distinct`D
References: #5134
Session.execute()
Session.get_bind()
Session.execute.bind_arguments
PReferences: #5573
eagerload()
relation()
joinedload()
relationship()
TReferences: #5192
Удалены все давно устаревшие классы «расширений», включая MapperExtension, SessionExtension, PoolListener, ConnectionProxy, AttributeExtension. Эти классы устарели с версии 0.7 и давно вытеснены системой слушателей событий.
References: #4638
joinedload_all
subqueryload_all
lazyload_all
selectinload_all
RReferences: #4642
comparable_property
hybrid
comparable_using
Rcompile_mappers
configure_mappers()
Rcollection.linker
AttributeEvents.init_collection()
AttributeEvents.dispose_collection()
RSession.prune
Session.weak_identity_map
Поведение при обращении к сеансамStrongInstanceDict
Rmapper.order_by
Query.order_by()
R``Session._enable_transaction_accounting``R
``Session.is_modified.passive``R
References: #4643
engine¶
Result
ResultProxy
CursorResult
ResultProxy
Result
IСм.также
asyncio extension greenlet asyncpg S
References: #3414
:paramref:`_sa.create_engine.future`I
References: #4644
Переработан набор диалектных хуков «setinputsizes()» с целью корректного расширения для любого произвольного DBAPI, позволяя диалектам иметь отдельные хуки, которые могут вызывать cursor.setinputsizes() в соответствующем для данного DBAPI стиле. В частности, это сделано для поддержки стиля использования pyodbc, который принципиально отличается от стиля использования cx_Oracle. Добавлена поддержка pyodbc.
References: #5649
Inspector.get_sequence_names()
Inspector.has_sequence()
Sequence
AReferences: #2056
Table.autoload_with
Inspector
Engine
Connection
TReferences: #4755
RowProxy
Row
ResultProxy
LegacyRow
Row
TReferences: #4710
Отключена проверка «unicode returns», выполняемая при запуске диалекта под управлением Python 3, которая уже много лет служит для проверки поведения текущего DBAPI на предмет того, возвращает ли он строки Python Unicode или Py2K для типов данных VARCHAR и NVARCHAR. Эта проверка по-прежнему выполняется по умолчанию под Python 2, однако механизм проверки этого поведения будет удален в SQLAlchemy 2.0, когда поддержка Python 2 также будет удалена.
String
returns_unicode_strings
String.RETURNS_CONDITIONAL
String.RETURNS_BYTES
TReferences: #5315
Функция «pre-ping» пула была доработана таким образом, чтобы не вызывать соединение DBAPI, которое только что было открыто в той же операции checkout. pre-ping применяется только к соединению DBAPI, которое уже было зарегистрировано в пуле и снова проверяется.
References: #4524
Connection.execution_options.schema_translate_map
#4645 #4808 RReferences: #5004
Connection
Session
.rollback()
TReferences: #4712
Dialect.on_connect()
Dialect.initialize()
AReferences: #5497
-
См.также
:ref:`change_5526`<
References: #5526
MetaData.bind
RemovedIn20Warning
Режим исключений в SQLAlchemy 2.0 TReferences: #4634
server_side_cursors
Connection.execution_options.stream_results
TConnection.connect()
Connection
TReferences: #5131
case_sensitive
create_engine()
TReferences: #4878
»Неявный автокоммит», то есть COMMIT, возникающий при выполнении DML- или DDL-оператора на соединении, является устаревшим и не будет входить в SQLAlchemy 2.0. Когда автокоммит вступает в силу, выдается предупреждение в стиле 2.0, чтобы вызывающий код мог быть скорректирован для использования явной транзакции.
MetaData.create_all()
Engine
AСм.также
References: #4846
-
References: #4877
Engine.run_callable()
Engine.transaction()
Engine.table_names()
Engine.has_table()
Inspector
DReferences: #4755
get_primary_keys
Dialect
Inspector
Dialect.get_pk_constraint()
Inspector.get_primary_keys()
Rdbapi_error
ConnectionEvents.dbapi_error
ConnectionEvents.handle_error()
ExecutionContext.is_disconnect
ExecutionContext.exception
RReferences: #4643
Dialect.reflecttable
Engine._run_visitor
TReferences: #4755
``Inspector.get_table_names.order_by``T
References: #4755
Inspector.reflecttable()
Inspector.reflect_table()
TReferences: #5244
sql¶
В компилятор SQL добавлена встроенная функция «линтинг из». Это позволяет компилятору вести граф всех предложений FROM в конкретном операторе SELECT, связанных критериями в WHERE или в JOIN, которые связывают эти предложения FROM вместе. Если между любыми двумя предложениями FROM нет пути, то выдается предупреждение о том, что запрос может порождать картезианское произведение. Поскольку язык выражений Core, а также ORM построены на модели «неявных FROM», когда конкретное предложение FROM автоматически добавляется, если на него ссылается какая-либо часть запроса, это легко может произойти случайно, и мы надеемся, что новая функция поможет решить эту проблему.
См.также
Встроенный линтинг FROM предупреждает о возможных картезианских произведениях в операторе SELECT
References: #4737
bindparam()
use_binds_for_limits
AСм.также
Новые «посткомпиляционные» связанные параметры, используемые для LIMIT/OFFSET в Oracle, SQL Server
References: #4808
Добавлена поддержка регулярных выражений на поддерживаемых бэкендах. Определены две операции:
Поддерживаются такие бэкенды, как SQLite, PostgreSQL, MySQL / MariaDB и Oracle.
References: #1390
select()
Query
_selectable.CompoundSelect
ColumnCollection
TСм.также
Объекты SELECT и производные предложения FROM допускают дублирование столбцов и меток столбцов
References: #4753
-
См.также
Выборка из самого запроса в качестве подзапроса, например, «from_self()».
Query.from_self()
<References: #5221
Функция «расширяющий IN», которая генерирует IN-выражения во время выполнения запроса, основываясь на конкретных параметрах, связанных с выполнением оператора, теперь используется для всех IN-выражений, составленных против списков литеральных значений. Это позволяет полностью кэшировать IN-выражения независимо от списка передаваемых значений, а также обеспечивает поддержку пустых списков. Для любого сценария, в котором IN-выражение содержит нелитеральные SQL-выражения, сохраняется прежнее поведение предварительного рендеринга для каждой позиции в IN. Изменение также завершает поддержку расширения IN кортежами, где ранее не действовали процессоры привязки, специфичные для типов.
References: #4645
:ticket:`4369`A
References: #5380
Index.create()
Index.drop()
Index.create.checkfirst
Table
Sequence
TReferences: #527
__str
ColumnCollection
CReferences: #5191
``FETCH {FIRST | NEXT} [ count ] {ROW | ROWS} {ONLY | WITH TIES}``A
References: #5576
CAST(table.colname AS INTEGER)
CAST(table.colname AS INTEGER) AS colname
Select.apply_labels()
<tablename>_<inner column name>
cast()
type_coerce()
AReferences: #4449
-
References: #4617
:class:`Values`A
References: #4868
select()
select(col1, col2, col3, ..)
select()
TReferences: #5284
SelectBase
FromClause
select()
select()
SelectBase.alias()
SelectBase.subquery()
AReferences: #4617
Subquery
Alias
SelectBase
Subquery
Alias
SelectBase.subquery()
SelectBase.alias()
AReferences: #4617
Всеобъемлющая реорганизация и рефакторинг внутренних компонентов Core и ORM теперь позволяет всем операторам Core и ORM в областях DQL (например, SELECT) и DML (например, INSERT, UPDATE, DELETE) в большинстве случаев полностью кэшировать SQL-компиляцию, а также построение метаданных для получения результата. Это фактически представляет собой прозрачную и обобщенную версию того, что предлагало расширение «Baked Query» для ORM в прошлых версиях. Новая возможность позволяет вычислять ключ кэша для любой конструкции SQL на основе строки, которую она в конечном итоге выдает для данного диалекта, что позволяет функциям, которые каждый раз составляют эквивалентный объект select(), Query(), insert(), update() или delete(), кэшировать этот оператор после того, как он будет сгенерирован в первый раз.
Эта возможность включается прозрачно, но включает в себя некоторые новые парадигмы программирования, которые могут быть использованы для повышения эффективности кэширования.
References: #4639
ForeignKey
UniqueConstraint
CheckConstraint
InstrumentedAttribute
FReferences: #5001
and_()
or_()
*args
and_()
or_()
and_(True, *args)
or_(False, *args)
*args
CReferences: #5054
tuple_()
tuple_()
select()
Query
CompileError
tuple_()
Bundle
IReferences: #5127
Улучшена поддержка имен столбцов, содержащих в строке знаки процента, в том числе исправлены проблемы с анонимными метками, в которых также присутствовало имя столбца со знаком процента, а также восстановлена поддержка имен связанных параметров со знаками процента в диалекте psycopg2 с использованием процесса позднего экранирования, аналогичного тому, который используется в диалекте cx_Oracle.
References: #5653
FunctionElement
Function
"SELECT myfunc() AS myfunc_1"
func
FunctionElement
CReferences: #4887
ClauseElement.compare()
ClauseElement
RReferences: #4336
``DISTINCT ON``D
References: #4002
_selectable.CompoundSelect
CompoundSelect.order_by()
Table
#4617.c
_selectable.CompoundSelect
CompoundSelect.selected_columns
CompoundSelect.order_by()
TReferences: #4617
-
References: #4621
:meth:`_sql.Join.alias`T
References: #5010
Table
Table.append_column.replace_existing
Table.append_column()
TEngine.contextual_connect
create_mock_engine()
TСм.также
:ref:`change_4393_threadlocal`<
References: #4632
sqlalchemy.sql.visitors.iterate_depthfirst
sqlalchemy.sql.visitors.traverse_depthfirst
iterate()
traverse()
RCompiler
.execute()
.scalar()
Compiler
Compiler
Engine
RCompiled.compile
ClauseElement.__and__
ClauseElement.__or__
Over.func
RFromClause.count
count
func
RReferences: #4643
text.bindparams
text.typemap
TextClause.bindparams()
TextClause.columns()
RTable.useexisting
Table.extend_existing
RReferences: #4643
Table
mustexist
Table.must_exist
<SelectBase.as_scalar()
Query.as_scalar()
SelectBase.scalar_subquery()
Query.scalar_subquery()
SelectBase
Alias
SelectBase.scalar_subquery()
SelectBase.scalar_subquery()
Subquery.as_scalar()
Alias.as_scalar
.scalar_subquery()
` :func:`_ ` object or :class:`_ T:func:`_expression.select`T
References: #4617
Несколько операторов переименованы для достижения более согласованного наименования в SQLAlchemy.
Изменения в операторе следующие:
isfalse
is_false
<isnot_distinct_from
is_not_distinct_from
<istrue
is_true
<notbetween
not_between
<notcontains
not_contains
<notendswith
not_endswith
<notilike
not_ilike
<notlike
not_like
<notmatch
not_match
<notstartswith
not_startswith
<nullsfirst
nulls_first
<nullslast
nulls_last
<isnot
is_not
<notin_
not_in
<
Поскольку эти операторы являются основными, внутренняя стратегия миграции при данном изменении заключается в том, чтобы поддерживать старые термины в течение длительного периода времени - если не бесконечно - но обновить всю документацию, учебные пособия и внутреннее использование новых терминов. Новые термины используются для определения функций, а старые термины были устаревшими и превращены в псевдонимы новых терминов.
-
References: #5498
Ключевое слово «NO ACTION» для внешнего ключа «ON UPDATE» теперь считается каскадом по умолчанию для внешнего ключа на всех поддерживающих бэкендах (SQlite, MySQL, PostgreSQL) и при обнаружении не включается в словарь отражений; такое поведение уже было для PostgreSQL и MySQL для всех предыдущих версий SQLAlchemy в любом случае. Ключевое слово «RESTRICT» положительно сохраняется при обнаружении; PostgreSQL сообщает об этом ключевом слове, а MySQL начиная с версии 8.0 - и подавно. В более ранних версиях MySQL оно не сообщается базой данных.
References: #4741
schema¶
Enum.create_constraint
Boolean.create_constraint
TReferences: #5367
``str()``C
References: #4262
Binary
LargeBinary
RReferences: #4643
Table.tometadata()
Table.to_metadata()
RReferences: #5413
:class:`_schema.Identity`A
extensions¶
:mod:`sqlalchemy.ext.compiled`C
References: #4887
AutomapBase.prepare.autoload_with
AutomapBase.prepare.reflect
AutomapBase.prepare.engine
AReferences: #5142
postgresql¶
Добавлена поддержка флагов PostgreSQL «readonly» и «deferrable» для всех диалектов psycopg2, asyncpg и pg8000. Это позволяет использовать преимущества новой обобщенной версии API «isolation level» для поддержки других видов атрибутов сессии, задаваемых через опции выполнения, которые надежно сбрасываются при возврате соединений в пул соединений.
См.также
References: #5549
BufferedRowResultProxy
stream_results=True
TReferences: #4914
При использовании диалекта psycopg2 для PostgreSQL минимальная версия psycopg2 установлена на уровне 2.7. Диалект psycopg2 опирается на многие возможности psycopg2, выпущенные за последние несколько лет, поэтому для упрощения диалекта минимальной версией теперь является версия 2.7, выпущенная в марте 2017 года.
``execute_values()``T
См.также
В диалекте psycopg2 по умолчанию реализована функция «execute_values» с RETURNING для операторов INSERT
executemany_mode
<References: #5401
``SQLAlchemy<1.4``T
Диалекты pygresql и py-postgresql устарели.
References: #5189
postgres://
postgresql://
RReferences: #4643
mysql¶
В диалект mysql добавлена поддержка MariaDB Connector/Python. Оригинальный pull request любезно предоставлен Георгом Рихтером.
References: #5459
:func:`_sa.create_engine`A
References: #5496
Sequence
Table
Table
Sequence
AReferences: #4976
:ticket:`4189`T
``with_for_update()``T
References: #5568
Кортеж server_version_info диалекта MySQL теперь имеет все числовые значения. Строковые маркеры типа «MariaDB» больше не присутствуют, так что числовое сравнение работает во всех случаях. Флаг .is_mariadb в диалекте должен использоваться для определения наличия или отсутствия mariadb. Дополнительно удалены конструкции, предназначенные для поддержки очень старых версий MySQL 3.x и 4.x; минимальная поддерживаемая версия MySQL теперь составляет 5.0.2.
References: #4189
Диалект OurSQL является устаревшим.
References: #5189
``mysql+gaerdbms``R
Удалить устаревший диалект
quoting
, которыйENUM
былSET
устаревшимmysql
с версии 1.0. Используйте диалект MySQLdb напрямую.References: #4643
sqlite¶
Для поддержки старых версий SQLite до 3.7.16, выпущенной в 2013 году, была прекращена поддержка перезаписи вложенных соединений справа. Ожидается, что все современные версии Python из числа тех, которые теперь поддерживаются, должны включать гораздо более новые версии SQLite.
References: #4895
mssql¶
Добавлена поддержка типа данных
JSON
на диалекте SQL Server с помощью реализацииJSON
, которая реализует функциональность SQL Server в формате JSON по отношению к типу данныхNVARCHAR(max)
в соответствии с документацией SQL Server. Реализация любезно предоставлена Гордом Томпсоном (Gord Thompson).References: #4384
Добавлена поддержка «CREATE SEQUENCE» и полная поддержка
Sequence
для Microsoft SQL Server. При этом удалена устаревшая возможность использования объектовSequence
для манипулирования характеристиками IDENTITY, которая теперь должна выполняться с помощьюmssql_identity_start
иmssql_identity_increment
, как описано в Поведение автоинкремента / Колонки IDENTITY. Изменение включает в себя новый параметрSequence.data_type
для учета выбора типа данных SQL Server, который для данного бэкенда включает INTEGER, BIGINT и DECIMAL(n, 0). Начальное значение по умолчанию для версии SQL ServerSequence
было установлено равным 1; это значение теперь выдается в DDL CREATE SEQUENCE для всех бэкендов.Улучшена поддержка покрывающих индексов (с колонками INCLUDE). Добавлена возможность для postgresql отображать операторы CREATE INDEX с предложением INCLUDE из Core. Отражение индексов также сообщает о столбцах INCLUDE отдельно как для mssql, так и для postgresql (11+).
References: #4458
Добавлена поддержка проверки/отражения частичных индексов/фильтрованных индексов, т.е. тех, которые используют параметры
mssql_where
илиpostgresql_where
, с помощьюIndex
. Запись является как частью словаря, возвращаемогоInspector.get_indexes()
, так и частью отраженной конструкцииIndex
, которая была отражена. Pull request любезно предоставлен Ramon Williams.References: #4966
Добавлена поддержка отражения временных таблиц с диалектом SQL Server. Имена таблиц с префиксом в виде знака фунта «#» теперь интроспектируются из системного каталога MSSQL «tempdb».
References: #5506
Ключевые слова SQL Server OFFSET и FETCH теперь используются для ограничения/смещения, а не с помощью оконной функции, для SQL Server версий 11 и выше. Для запроса, содержащего только LIMIT, по-прежнему используется TOP. Pull request любезно предоставлен Elkin.
References: #5084
Исправлена проблема, при которой
sqlalchemy.engine.reflection.has_table()
всегда возвращалоFalse
для временных таблиц.References: #5597
Исправлен базовый класс типа данных
DATETIMEOFFSET
, который должен быть основан на иерархии классовDateTime
, так как это тип данных, хранящий время.References: #4980
Диалекты adodbapi и mxODBC устарели.
References: #5189
Диалект mssql предполагает, что используется как минимум MSSQL 2005. При обнаружении предыдущей версии исключений не возникает, но операции могут не выполняться для старых версий.
В рамках поддержки отражения объектов
Identity
методInspector.get_columns()
больше не возвращаетmssql_identity_start
иmssql_identity_increment
как частьdialect_options
. Вместо этого используется информация в ключеidentity
.References: #5527
Утратил актуальность параметр
legacy_schema_aliasing
, превратив его вsqlalchemy.create_engine()
. Это давно устаревший параметр, по умолчанию имеющий значение False с версии 1.1.References: #4809
oracle¶
Максимальная длина идентификатора (max_identifier_length) для диалекта Oracle теперь по умолчанию равна 128 символам, если только при первом подключении не используется версия совместимости менее 12.2, в этом случае используется традиционная длина в 30 символов. Это продолжение проблемы, зафиксированной в серии 1.3, в которой добавлено определение максимальной длины идентификатора при первом подключении, а также предупреждение об изменении сервера Oracle.
См.также
Максимальная длина идентификатора - в документации по диалекту Oracle
References: #4857
Схема LIMIT / OFFSET, используемая в Oracle, теперь использует именованные, а не неименованные подзапросы, когда прозрачно переписывает оператор SELECT на тот, который использует подзапрос, включающий ROWNUM. Это изменение является частью более масштабного изменения, в результате которого неименованные подзапросы больше не поддерживаются непосредственно в Core, а также модернизирует внутреннее использование конструкции select() в диалекте Oracle.
Корректное отображение опций столбцов
Sequence
иIdentity
nominvalue
иnomaxvalue
какNOMAXVALUE` and ``NOMINVALUE
в базе данных oracle.Класс
INTERVAL
диалекта Oracle теперь корректно является подклассом абстрактной версииInterval
, а также корректным «эмулированным» базовым классом, что обеспечивает корректное поведение как в родном, так и в неродном режимах; ранее он был основан только наTypeEngine
.References: #4971