1.0 Changelog¶
1.0.19¶
Released: August 3, 2017oracle¶
Исправлена регрессия производительности, вызванная исправлением #3937, когда cx_Oracle начиная с версии 5.3 исключал из своего пространства имен символ
.UNICODE
, что интерпретировалось как безусловное включение режима cx_Oracle «WITH_UNICODE», вызывающего на стороне SQLAlchemy функции безусловного преобразования всех строк в юникод и приводящего к снижению производительности. На самом деле, по словам автора cx_Oracle, начиная с версии 5.1 режим «WITH_UNICODE» был полностью удален, поэтому дорогостоящие функции преобразования юникода больше не нужны и отключаются, если cx_Oracle 5.1 или выше обнаружен под Python 2. Также восстановлено предупреждение о недопустимости использования режима «WITH_UNICODE», которое было удалено при #3937.References: #4035
1.0.18¶
Released: July 24, 2017oracle¶
Исправление режима WITH_UNICODE в cx_Oracle, которое было обнаружено в результате того, что cx_Oracle 5.3 теперь жестко кодирует этот флаг в сборке; внутренний метод, использующий этот режим, не использовал правильную сигнатуру.
References: #3937
tests¶
Исправлена проблема в тестировании фикстур, которая была несовместима с изменением, внесенным в Python 3.6.2 в отношении менеджеров контекста.
References: #4034
1.0.17¶
Released: January 17, 2017orm¶
misc¶
Исправлено DeprecationWarnings для Python 3.6, связанное с экранированными строками без модификатора „r“, а также добавлено тестовое покрытие для Python 3.6.
References: #3886
1.0.16¶
Released: November 15, 2016orm¶
Исправлена ошибка в
Session.bulk_update_mappings()
, когда атрибут первичного ключа с альтернативным именем не отслеживался должным образом в операторе UPDATE.References: #3849
Исправлена ошибка, при которой объединенная ускоренная загрузка приводила к ошибке для полиморфно загруженного отображателя, когда параметр polymorphic_on был установлен на не отображенное выражение, например, на CASE-выражение.
References: #3800
Исправлена ошибка, при которой некорректно вызывалась ошибка ArgumentError, связанная с некорректной привязкой, переданной в сессию через
Session.bind_mapper()
,Session.bind_table()
или конструктор.References: #3798
Исправлена ошибка в
Session.bulk_save()
, при которой UPDATE некорректно работал в связке с отображением, реализующим счетчик идентификаторов версий.References: #3781
Исправлена ошибка, из-за которой аксессоры
Mapper.attrs
,Mapper.all_orm_descriptors
и другие производные атрибуты не обновлялись, если свойства mapper или другие ORM-конструкции были добавлены к mapper/классу после первого вызова этих аксессоров.References: #3778
mssql¶
Изменен запрос, используемый для получения «имени схемы по умолчанию», с запроса к таблице principals базы данных на использование функции «schema_name()», поскольку были получены сообщения о том, что прежняя система была недоступна в редакции Azure Data Warehouse. Есть надежда, что это наконец-то будет работать во всех версиях SQL Server и стилях аутентификации.
References: #3810
Обновлена схема получения информации о версии сервера для pyodbc, чтобы использовать SQL Server SERVERPROPERTY(), а не полагаться на pyodbc.SQL_DBMS_VER, который продолжает оставаться ненадежным, особенно при использовании FreeTDS.
References: #3814
В список исключений разъединения, приводящих к сбросу пула соединений, добавлен код ошибки 20017 «unexpected EOF from the server». Pull request любезно предоставлен Кеном Роббинсом (Ken Robbins).
References: #3791
Исправлена ошибка в диалекте pyodbc (а также в основном нерабочем диалекте adodbapi), когда точка с запятой в полях password или username могла быть интерпретирована как разделитель для другого токена; теперь при наличии точки с запятой значения берутся в кавычки.
References: #3762
misc¶
Исправлена ошибка, при которой установка подкласса single-table inh подкласса joined-table, включающего дополнительный столбец, приводила к повреждению коллекции внешних ключей сопоставленной таблицы, что мешало инициализации отношений.
References: #3797
1.0.15¶
Released: September 1, 2016orm¶
sql¶
Исправлена ошибка в
Table
, когда внутренний метод_reset_exported()
приводил к повреждению состояния объекта. Этот метод предназначен для выбираемых объектов и в некоторых случаях вызывается ORM; ошибочная конфигурация маппера могла привести к тому, что ORM вызывал этот метод на объектеTable
.References: #3755
mysql¶
Добавлена поддержка разбора булевых и целочисленных аргументов MySQL/Connector в строке запроса URL: connection_timeout, connect_timeout, pool_size, get_warnings, raise_on_warnings, raw, consume_results, ssl_verify_cert, force_ipv6, pool_reset_session, compress, allow_local_infile, use_pure.
References: #3787
misc¶
Исправлена ошибка в
sqlalchemy.ext.baked
, когда при использовании нескольких загрузчиков подзапросов разворачивание запроса с жадным загрузчиком подзапросов заканчивалось неудачей из-за проблемы с объемом переменной. Pull request любезно предоставлен Марком Ханенбергом (Mark Hahnenberg).References: #3743
1.0.14¶
Released: July 6, 2016examples¶
Исправлена регрессия, возникавшая в примере examples/vertical/dictlike-polymorphic.py, из-за которой он не запускался.
References: #3704
engine¶
Исправлена ошибка отражения кросс-схемного внешнего ключа в сочетании с аргументом
MetaData.schema
, при которой ссылающаяся таблица, присутствующая в схеме «по умолчанию», терпела неудачу, так как не было возможности указатьTable
, имеющую для схемы «пусто». В качестве доступного значения дляTable.schema
иSequence.schema
добавлен специальный символsqlalchemy.schema.BLANK_SCHEMA
, указывающий на то, что имя схемы должно быть принудительноNone
, даже если указаноMetaData.schema
.References: #3716
sql¶
Исправлена проблема с оператором отрицания в математике SQL, когда тип выражения переставал соответствовать числовому типу оригинала. Это приводило к проблемам, когда тип определял поведение набора результатов.
References: #3735
Исправлена ошибка, из-за которой методы
__getstate__
/__setstate__
для sqlalchemy.util.Properties были нерабочими в связи с переходом в серии 1.0 на__slots__
. Данная проблема потенциально могла повлиять на некоторые сторонние приложения. Pull request любезно предоставлен Питером Малдером (Pieter Mulder).References: #3728
Функция
FromClause.count()
ожидает снятия с эксплуатации в версии 1.1. Эта функция использует произвольный столбец в таблице и не является надежной; для использования в Core следует предпочестьfunc.count()
.References: #3724
Исправлена ошибка в структуре
CTE
, из-за которой она не клонировалась должным образом при использовании объединения, как это часто бывает в рекурсивных CTE. Неправильное клонирование приводило к ошибкам при использовании CTE в различных контекстах ORM, например, в контекстеcolumn_property()
.References: #3722
Исправлена ошибка, при которой
Table.tometadata()
создавал дубликатUniqueConstraint
для каждого объектаColumn
, содержащего параметрunique=True
.References: #3721
postgresql¶
Исправлена ошибка, из-за которой типы
TypeDecorator
иVariant
недостаточно глубоко проверялись диалектом PostgreSQL, чтобы определить, что нужно выводить SMALLSERIAL или BIGSERIAL, а не SERIAL.References: #3739
oracle¶
Исправлена ошибка в
Select.with_for_update.of
, когда подход Oracle «rownum» к LIMIT/OFFSET не учитывал выражения внутри клаузы «OF», которые должны быть указаны на самом верхнем уровне, ссылаясь на выражения внутри подзапроса. Теперь эти выражения добавляются в подзапрос, если это необходимо.References: #3741
1.0.13¶
Released: May 16, 2016orm¶
Исправлена ошибка в стратегии «evaluate» операторов
Query.update()
иQuery.delete()
, из-за которой не учитывался связанный параметр с «вызываемым» значением, как это происходит при фильтрации по выражению равенства «многие-к-одному» вдоль отношения.References: #3700
Исправлена ошибка, из-за которой слушатели событий, используемые для обратных ссылок, могли быть случайно применены несколько раз при использовании глубокой иерархии наследования классов в сочетании с несколькими шагами настройки отображателя.
References: #3710
Исправлена ошибка, при которой передача конструкции
text()
в методQuery.group_by()
приводила к ошибке, вместо того чтобы интерпретировать объект как SQL-фрагмент.References: #3706
Анонимная маркировка применяется к конструкции
func
, которая передается вcolumn_property()
, так что если один и тот же атрибут дважды упоминается как выражение столбца, то имена де-анонимизируются, что позволяет избежать ошибок «двусмысленного столбца». Ранее для деанонимизации имени необходимо было применить конструкцию.label(None)
.References: #3663
Исправлена ошибка, возникавшая в серии 1.0 при загрузке ORM, когда исключение, возникающее при отсутствии ожидаемого столбца, ошибочно выдавало ошибку
NoneType
, а не ожидаемуюNoSuchColumnError
.References: #3658
examples¶
Изменен пример «направленный граф», в котором больше не считаются значимыми целочисленные идентификаторы узлов; ссылки «выше»/»ниже» теперь допускают взаимное расположение ребер в обоих направлениях.
References: #3698
sql¶
Исправлена ошибка, из-за которой при использовании
case_sensitive=False
сEngine
в наборе результатов неправильно учитывались дублирующиеся имена столбцов, что приводило к ошибке при выполнении оператора в версии 1.0 и не позволяло сработать исключению «неоднозначный столбец» в версии 1.1.References: #3690
Исправлена ошибка, при которой отрицание выражения EXISTS не типизировалось в результате как boolean, а также не выполнялся анонимный алиасинг в списке SELECT, как это происходит в случае неотрицательной конструкции EXISTS.
References: #3682
Исправлена ошибка, при которой исключение «unconsumed column names» не вызывалось в случае, когда
Insert.values()
вызывался со списком отображений параметров, а не с одним отображением параметров. Pull request любезно предоставлен Athena Yao.References: #3666
postgresql¶
Добавлена поддержка обнаружения разъединения для строки ошибки «SSL error: decryption failed or bad record mac». Pull request любезно предоставлен Iuri de Silvio.
References: #3715
mssql¶
Исправлена ошибка, при которой в предложении ROW_NUMBER OVER, применяемом для селектов OFFSET в SQL Server, неправомерно подставлялся простой столбец из локального оператора, совпадающий с именем метки, используемой в критерии ORDER BY этого оператора.
References: #3711
Исправлена ошибка, появившаяся в серии 1.0, из-за которой диалекты Oracle и SQL Server неправильно учитывали столбцы результирующего набора, когда эти диалекты оборачивали SELECT в подзапрос для обеспечения поведения LIMIT/OFFSET, а исходный оператор SELECT ссылался на один и тот же столбец несколько раз, например, на столбец и на метку этого же столбца. Эта проблема связана с #3658 тем, что при возникновении ошибки она также вызывала ошибку
NoneType
, а не сообщала, что не может найти столбец.References: #3657
oracle¶
Исправлена ошибка в процессе подключения cx_Oracle, которая приводила к ошибке TypeError, когда пользователь, пароль или dsn были пустыми. Это препятствовало внешней аутентификации в базах данных Oracle и не позволяло подключиться к стандартному dsn. Строка connect oracle:// теперь позволяет подключиться к dsn по умолчанию, используя имя пользователя операционной системы, что эквивалентно подключению по „/“ в sqlplus.
References: #3705
Исправлена ошибка в прокси-сервере результатов, используемом Oracle в основном при работе с бинарными и другими LOB-типами, из-за которой при использовании кэширования запросов и операторов процессоры результатов на уровне типа, в частности, требуемые самим бинарным типом, а также любые другие процессоры, терялись после первого выполнения оператора из-за удаления их из метаданных кэшированных результатов.
References: #3699
misc¶
Исправлена ошибка в преобразовании «to_list», когда одиночный объект bytes превращался в список отдельных символов. Это влияло, в частности, на использование метода
Query.get()
на первичном ключе, являющемся объектом bytes.References: #3660
1.0.12¶
Released: February 15, 2016orm¶
Исправлена ошибка в
Session.merge()
, когда объект с составным первичным ключом, имеющим значения для некоторых, но не всех полей PK, выдавал оператор SELECT, вставляя в запрос внутренний символ NEVER_SET, вместо того чтобы определить, что этот объект не имеет первичного ключа с возможностью поиска и SELECT не должен выдаваться.References: #3647
Исправлена ошибка, возникшая в версии 0.9, когда система опций загрузчика в стиле 0.9 не учитывала несколько опций загрузчика
undefer_group()
в одном запросе. Теперь несколько вариантовundefer_group()
будут учитываться даже для одной и той же сущности.References: #3623
engine¶
Пересмотр #2696, впервые выпущенного в версии 1.0.10, который пытается обойти отсутствие в Python 2 контекстного сообщения об исключениях, выдавая предупреждение об исключении, которое было прервано вторым исключением при попытке отката уже завершившейся транзакции; эта проблема продолжает возникать для бэкендов MySQL в сочетании с неожиданно потерянной точкой сохранения, которая при попытке отката вызывает ошибку «нет такой точки сохранения», не позволяя понять, в чем заключалось исходное состояние.
Подход был обобщен на функцию Core «safe reraise», которая выполняется в ORM и Core в любом месте, где происходит откат транзакции в ответ на ошибку, возникшую при попытке фиксации, включая контекстные менеджеры, предоставляемые
Session
иConnection
, и выполняется для таких операций, как сбой на «RELEASE SAVEPOINT». Ранее исправление действовало только для определенного пути в рамках процесса ORM flush/commit; теперь оно действует и для всех транзакционных менеджеров контекста.References: #2696
sql¶
Исправлена проблема, при которой флаг «literal_binds» не распространялся для конструкций
insert()
,update()
илиdelete()
при компиляции в строковый SQL. Pull request любезно предоставлен Тимом Тейтом.References: #3643
Исправлена проблема, когда непреднамеренное использование переопределения Python
__contains__
с выражением столбца (например, с помощью'x' in col
) приводило к бесконечному циклу в случае типа ARRAY, так как Python переключает доступ на__getitem__
, который никогда не возникает для этого типа. В целом, все использование__contains__
теперь вызывает ошибку NotImplementedError.References: #3642
Исправлена ошибка в конструкции метаданных
Table
, появившаяся примерно в серии 0.9, когда при добавлении столбцов вTable
, который не был распакован, не удавалось правильно установитьColumn
в коллекцию „c“, что приводило к проблемам в таких областях, как настройка ORM. Это могло повлиять на такие примеры использования, какextend_existing
и другие.References: #3632
postgresql¶
mssql¶
Исправлен синтаксис функции
extract()
при использовании ее на MSSQL по отношению к значению datetime; убраны кавычки вокруг ключевого слова. Pull request любезно предоставлен Гийомом Думенком (Guillaume Doumenc).References: #3624
Исправлена ошибка версии 1.0, в результате которой для оператора UPDATE или DELETE, переданного в виде обычного текста или с помощью конструкции
text()
, больше не вызывалась опережающая выборка cursor.rowcount, что влияло на те драйверы, которые стирают cursor.rowcount после закрытия курсора, например, драйверы SQL Server ODBC и Firebird.References: #3622
oracle¶
Исправлена небольшая проблема в компиляторе Jython Oracle, связанная с отображением «RETURNING», что позволяет этому в настоящее время не поддерживаемому/непроверяемому диалекту рудиментарно работать с серией 1.0. Pull request любезно предоставлен Карлосом Ривасом.
References: #3621
misc¶
Исправлена ошибка, из-за которой некоторые сценарии перевыполнения исключений присоединяли исключение к себе в качестве «причины»; хотя интерпретатор Python 3 не возражает против этого, в iPython это могло привести к бесконечным циклам.
References: #3625
1.0.11¶
Released: December 22, 2015orm¶
Исправлена регрессия, вызванная в 1.0.10 исправлением #3593, когда добавленная проверка на полиморфную объединенную загрузку из соединения poly_subclass->class->poly_baseclass при сценарии class->poly_subclass->class давала сбой.
References: #3611
Исправлена ошибка, при которой
Session.bulk_update_mappings()
и связанные с ним словари не сбивали счетчик идентификатора версии при его использовании. Опыт работы здесь пока не очень удачный, так как в данных словарях требуется исходный идентификатор версии, а чистого сообщения об ошибке пока нет.References: #3610
Основные исправления флага
Mapper.eager_defaults
. Этот флаг некорректно использовался в том случае, если необходимо было выполнить несколько операторов UPDATE, как часть операции flush или массового обновления. Кроме того, в операторах обновления без необходимости выдавался RETURNING.References: #3609
Исправлена ошибка, при которой использование метода
Query.select_from()
приводило к неудаче при последующем вызове методаQuery.with_parent()
.References: #3606
sql¶
Исправлена ошибка в
Update.return_defaults()
, из-за которой все удерживающие столбцы по умолчанию вставки, не включенные в предложение SET (например, столбцы первичного ключа), выводились в RETURNING, несмотря на то, что это UPDATE.References: #3609
mysql¶
Внесены изменения в регулярное выражение, используемое для разбора представлений MySQL, в результате чего мы больше не предполагаем наличие ключевого слова «ALGORITHM» в отраженном источнике представления, так как некоторые пользователи сообщали о его отсутствии в некоторых средах Amazon RDS.
References: #3613
В диалект MySQL 5.7 добавлены новые зарезервированные слова для MySQL 5.7, включая „generated“, „optimizer_costs“, „stored“, „virtual“. Pull request любезно предоставлен Hanno Schlichting.
misc¶
Дополнительные исправления в методе #3605, методе pop на
MutableDict
, где не учитывался аргумент «по умолчанию».References: #3605
Исправлена ошибка в системе запеченных загрузчиков, когда общесистемный monkeypatch для настройки запеченных ленивых загрузчиков вмешивался в работу других стратегий загрузчиков, которые полагаются на ленивую загрузку в качестве запасного варианта, например, joined и subquery eager loaders, что приводило к исключениям
IndexError
во время настройки маппера.References: #3612
1.0.10¶
Released: December 11, 2015orm¶
Исправлена проблема, при которой post_update для отношения «многие-к-одному» не выдавал UPDATE в случае, когда атрибут был установлен в None и не был загружен ранее.
References: #3599
Исправлена ошибка, которая на самом деле является регрессией, возникшей между версиями 0.8.0 и 0.8.1 по причине #2714. В случае, когда при использовании функции «with_polymorphic» необходимо соединиться через отношение, связанное с подклассом, не удавалось соединиться с правильной сущностью.
References: #3593
Исправлена ошибка с объединенной загрузкой, которая возникала, когда a. запрос содержит критерии ограничения/смещения, вынуждающие выполнять подзапрос b. отношение использует «вторичный» ключ c. primaryjoin отношения ссылается на столбец, который либо не является частью первичного ключа, либо является PK col в объединенной таблице подкласса наследования, который имеет другое имя атрибута, чем столбец первичного ключа родительской таблицы d. в запросе отложены столбцы, которые присутствуют в primaryjoin, как правило, через невключение в load_only(); необходимый столбец (столбцы) не будет присутствовать в подзапросе, что приведет к некорректному SQL.
References: #3592
Редкий случай, когда операция
Session.rollback()
не работает в области действия операцииSession.flush()
, вызывающей исключение, как это наблюдалось в некоторых случаях с MySQL SAVEPOINT, не позволяет заметить исходное исключение базы данных, когда оно было вызвано при флеше, но только на Py2K, поскольку Py2K не поддерживает цепочку исключений; на Py3K исходное исключение цепляется. В качестве обходного пути в данном конкретном случае выдается предупреждение, показывающее, по крайней мере, строковое сообщение исходной ошибки базы данных, прежде чем мы перейдем к вызову исключения, вызвавшего откат.References: #2696
orm declarative¶
Исправлена ошибка, из-за которой в Py2K юникодный литерал не принимался в качестве строкового имени класса или другого аргумента в декларативном использовании
backref()
наrelationship()
. Pull request любезно предоставлен Nils Philippsen.
sql¶
Добавлена поддержка упорядоченных по параметрам предложений SET в операторе UPDATE. Эта возможность доступна при передаче флага
update.preserve_parameter_order
либо в основной конструкцииUpdate
, либо при добавлении его в словарьQuery.update.update_args
на уровне ORM, также передавая сами параметры в виде списка из 2 кортежей. Спасибо Горке Эгилеору за реализацию и тесты.Исправлена проблема в конструкции
Insert.from_select()
, из-за которой при компиляции конструкцииInsert
, когда целевая конструкцияTable
имеет значения по умолчанию на стороне Python, в конструкцииSelect
происходило искажение коллекции._raw_columns
на месте. При этом конструкцияSelect
будет компилироваться отдельно с ошибочным столбцом, присутствующим после компиляцииInsert
, а сам операторInsert
при повторной попытке компиляции окажется неудачным из-за дублирования связанных параметров.References: #3603
Исправлена ошибка, когда при создании таблицы CREATE TABLE с таблицей без столбцов, но с ограничениями, такими как ограничение CHECK, в определении ставилась ошибочная запятая; такой сценарий может возникнуть, например, в таблице PostgreSQL INHERITS, не имеющей собственных столбцов.
References: #3598
postgresql¶
Исправлена проблема, при которой специфичный для PostgreSQL модификатор SELECT «FOR UPDATE OF» не срабатывал, если ссылающаяся таблица имела квалификатор схемы; в PG имя схемы должно быть опущено. Pull request любезно предоставлен Дианой Кларк.
References: #3573
Исправлена ошибка, при которой некоторые разновидности SQL-выражений, передаваемых в предложение «where» в
ExcludeConstraint
, не принимались корректно. Pull request courtesy aisch.Исправлен атрибут
.python_type
вINTERVAL
, чтобы он возвращалdatetime.timedelta
так же, как и атрибутpython_type
, а не поднималNotImplementedError
.References: #3571
mysql¶
mssql¶
Добавлена ошибка «20006: Write to the server failed» в список ошибок разъединения для драйвера pymssql, поскольку, по наблюдениям, эта ошибка приводит к невозможности установить соединение.
References: #3585
В случае возврата SQL-сервером недопустимого формата даты или времени из столбца DATE или TIME теперь выдается описательная ошибка ValueError, а не ошибка NoneType. Pull request любезно предоставлен Эдом Ависом.
Исправлена проблема, при которой DDL, сгенерированные для типов MSSQL DATETIME2, TIME и DATETIMEOFFSET с точностью «ноль», не генерировали поле точности. Pull request любезно предоставлен Jacobo de Vera.
tests¶
Учебники по ORM и Core, которые всегда были представлены в формате doctest, теперь выполняются в рамках обычного набора модульных тестов как в Python 2, так и в Python 3.
misc¶
В класс
MutableDict
добавлена поддержка методовdict.pop()
иdict.popitem()
.References: #3605
Обновления внутренних вызовов getargspec(), некоторые обновления фикстур, связанные с py36, и изменения в двух итераторах, чтобы они «возвращались», а не поднимали StopIteration, чтобы тесты проходили без ошибок и предупреждений на Py3.5, Py3.6, pull requests courtesy Jacob MacDonald, Luri de Silvio, and Phil Jones.
Исправлена проблема, когда метод .get(), используемый напрямую или в рамках ленивой загрузки, не учитывал «get clause» мэппера как часть ключа кэша, что приводило к несовпадению связанных параметров при повторном генерировании клаузулы. Это условие кэшируется картографами «на лету», но в сценариях с высокой степенью параллельности может генерироваться более одного раза при первом обращении.
References: #3597
1.0.9¶
Released: October 20, 2015orm¶
Добавлен новый метод
Query.one_or_none()
; аналогиченQuery.one()
, но возвращает None, если строка не найдена. Pull request любезно предоставлен esiegerman.В версии 1.0 исправлена ошибка, из-за которой новая возможность использования «executemany» для операторов UPDATE в ORM (например, Операторы UPDATE теперь объединяются в пакет с executemany() при промывке) при использовании схем генерации версий на стороне сервера приводила к поломке PostgreSQL и других бэкендов с RETURNING, так как значение на стороне сервера получалось через RETURNING, что не поддерживается с executemany.
References: #3556
Исправлена редкая ошибка TypeError, которая могла возникать при структурировании некоторых видов опций внутреннего загрузчика колонок во внутреннем протоколировании.
References: #3539
Исправлена ошибка в
Session.bulk_save_objects()
, когда отображаемый столбец, имеющий какое-либо значение типа «fetch on update» и не присутствующий локально в данном объекте, приводил к ошибке AttributeError внутри операции.References: #3525
Исправлена ошибка версии 1.0, при которой стратегия загрузчика «noload» не работала для отношений «многие-к-одному». Загрузчик использовал API для помещения «None» в словарь, который больше не записывал значение; это побочный эффект #3061.
References: #3510
examples¶
Исправлены две проблемы в примере «history_meta», когда при отслеживании истории могли встречаться пустые истории, а также когда колонка, ключ которой был привязан к альтернативному имени атрибута, не отслеживалась должным образом. Исправления предоставлены Алексом Фрейзером.
sql¶
Исправлена ошибка в выпущенном в 1.0 default-процессоре для оператора вставки multi-VALUES, #3288, из-за которой тип столбца, удерживающего значение по умолчанию, не передавался в скомпилированный оператор в случае использования значения по умолчанию, что приводило к невызову обработчиков типов на уровне биндов.
References: #3520
postgresql¶
Исправление новой функции PostgreSQL по отражению опций хранения и USING of #3455, выпущенной в 1.0.6, заключается в отключении этой функции для версий PostgreSQL < 8.2, в которых столбец
reloptions
не предусмотрен; это позволяет Amazon Redshift снова работать, поскольку он основан на версии PostgreSQL 8.0.x. Исправление любезно предоставлено Питом Холлобоном.
oracle¶
Исправлена поддержка cx_Oracle версии 5.2, из-за которой SQLAlchemy сбивался с определения версии под Python 3 и случайно не использовал правильный режим юникода для Python 3. Это приводило к тому, что связанные переменные неверно интерпретировались как NULL, а строки не возвращались.
This change is also backported to: 0.7.0b1
References: #3491
Исправлена ошибка в диалекте Oracle, при которой отражение таблиц и других символов с именами, заключенными в кавычки для принудительного перевода во все строчные регистры, не идентифицировалось должным образом в запросах на отражение. Конструкция
quoted_name
теперь применяется к входящим именам символов, которые в процессе «нормализации имен» определяются как принудительно переведенные во все нижние регистры.References: #3548
misc¶
В конструктор
AssociationProxy
добавлен параметрAssociationProxy.info
, соответствующий аксессоруAssociationProxy.info
, который был добавлен в #2971. Это стало возможным благодаря тому, чтоAssociationProxy
конструируется явно, в отличие от гибрида, который конструируется неявно через синтаксис декоратора.References: #3551
Исправлены две проблемы, связанные с отражением Sybase, позволяющие отражать таблицы без первичных ключей, а также гарантирующие, что SQL-оператор, участвующий в определении внешнего ключа, предварительно фетчится, чтобы избежать проблем с драйверами при вложенных запросах. Исправления предоставлены Евгением Запольским; обратите внимание, что в настоящее время мы не можем протестировать Sybase для локальной проверки этих изменений.
1.0.8¶
Released: July 22, 2015engine¶
Исправлена критическая проблема, из-за которой обработчик события «checkout» пула мог быть вызван для недействительного соединения без вызова обработчика события «connect», в случае если пул пытался переподключиться после аннулирования и потерпел неудачу; при этом недействительное соединение оставалось и использовалось при последующих попытках. Эта проблема сильнее проявляется в сериях 1.0, начиная с 1.0.2, так как в обработчике события также передается очищенный словарь
.info
; до 1.0.2 словарь.info
остается прежним.This change is also backported to: 0.7.0b1
References: #3497
sqlite¶
Исправлена ошибка в диалекте SQLite, при которой отражение UNIQUE-ограничений, включающих в имена неалфавитные символы, например точки или пробелы, не отражалось их именем.
This change is also backported to: 0.9.10
References: #3495
misc¶
Исправлена проблема, когда определенный базовый класс в составе utils не реализовывал
__slots__
, а значит, и все подклассы этого класса не реализовывали , что сводило на нет смысл использования__slots__
. Это не вызвало никаких проблем, за исключением IronPython, который, по-видимому, не реализует поведение__slots__
совместимо с cPython.References: #3494
1.0.7¶
Released: July 20, 2015orm¶
Исправлена регрессия 1.0, когда объекты значений, переопределяющие
__eq__()
для возврата объекта с небулевыми возможностями, например, некоторые типы geoalchemy, а также типы numpy, проверялись наbool()
во время операции обновления единицы работы, тогда как в 0.9 возвращаемое значение__eq__()
проверялось на «is True», чтобы защитить от этого.References: #3469
Исправлена ошибка версии 1.0, когда «отложенный» атрибут не заполнялся корректно, если он был загружен в рамках «оптимизированной загрузки наследования», которая представляет собой специальный SELECT, выдаваемый в случае наследования объединенной таблицы и используемый для заполнения просроченных или невыгруженных атрибутов в объединенной таблице без загрузки базовой таблицы. Это связано с тем, что SQLA 1.0 больше не догадывается о загрузке отложенных столбцов и должна быть направлена явно.
References: #3468
Исправлена ошибка версии 1.0, когда «родительская сущность» атрибута, сопоставленного с синонимом, поверх объекта
aliased()
, разрешалась в исходный сопоставитель, а не в его версиюaliased()
, что создавало проблемы дляQuery
, который полагается на этот атрибут (например, это единственный представительный атрибут, заданный в конструкторе), чтобы определить правильное предложение FROM для запроса.References: #3466
orm declarative¶
Исправлена ошибка в расширении
AbstractConcreteBase
, когда колонка, заданная в базе ABC и имеющая имя атрибута, отличное от имени колонки, не отображалась корректно в конечном базовом классе. В версии 0.9 ошибка не проявляла себя, в то время как в версии 1.0 она приводила к ошибке ArgumentError, поэтому до версии 1.0 она могла быть не замечена.References: #3480
engine¶
Исправлена ошибка, при которой новые методы на
ResultProxy
, используемые объектом ORMQuery
(часть улучшения производительности #3175), не вызывали исключения «этот результат не возвращает строки» в случае, когда драйвер (обычно MySQL) не может правильно сгенерировать cursor.description; вместо этого возникала ошибка AttributeError против NoneType.References: #3481
Исправлена регрессия, при которой
ResultProxy.keys()
возвращал нескорректированные имена внутренних символов для «анонимных» меток, которые представляют собой метки типа «foo_1», генерируемые для SQL-функций без меток и подобных им. Это было побочным эффектом повышения производительности, реализованного в #918.References: #3483
sql¶
Добавлен метод
ColumnElement.cast()
, выполняющий ту же задачу, что и самостоятельная функцияcast()
. Pull request любезно предоставлен Себастьяном Банком.References: #3459
Исправлена ошибка, при которой при коэрцитивности литеральной константы
True
илиFalse
в сочетании сand_()
илиor_()
возникала ошибка AttributeError.References: #3490
Исправлена потенциальная проблема, при которой пользовательский подкласс
FunctionElement
или другой элемент колонки, некорректно указывающий в качестве атрибута.type
„None“ или любой другой недопустимый объект, будет сообщать об этом исключении вместо переполнения рекурсии.References: #3485
Исправлена ошибка, при которой оператор modulus SQL не работал в обратном направлении из-за отсутствия метода
__rmod__
. Pull request любезно предоставлен dan-gittik.
schema¶
Добавлена поддержка аргументов MINVALUE, MAXVALUE, NO MINVALUE, NO MAXVALUE и CYCLE для CREATE SEQUENCE в соответствии с поддержкой PostgreSQL и Oracle. Pull request любезно предоставлен jakeogh.
1.0.6¶
Released: June 25, 2015orm¶
В версии 1.0 исправлена серьезная ошибка, из-за которой функция version_id_counter приводила к увеличению счетчика версий объекта, когда в строке объекта не происходило никаких изменений, но вместо этого с ним ассоциировались или деассоциировались объекты, связанные с ним через отношения (например, обычно многие к одному), в результате чего оператор UPDATE обновлял счетчик версий объекта и ничего больше. В случае использования относительно недавней функции счетчика версий «на стороне сервера» и/или «программно/условно» (например, установка значения version_id_generator в False) ошибка могла привести к появлению UPDATE без корректного предложения SET.
References: #3465
Исправлена ошибка версии 1.0, при которой улучшенное поведение однонаследственных объединений #3222 происходило неадекватно для JOIN по явным критериям объединения с однонаследственным подклассом, не использующим никакого дискриминатора, что приводило к появлению дополнительного предложения «AND NULL».
References: #3462
Исправлена ошибка в новой функции
Session.bulk_update_mappings()
, когда столбцы первичного ключа, используемые в предложении WHERE для нахождения строки, включались также в предложение SET, излишне устанавливая их значение в себя. Pull request любезно предоставлен Патриком Хейсом.References: #3451
Исправлена регрессия, связанная с непредвиденным использованием, когда пользовательские объекты
Comparator
, использующие метод__clause_element__()
и возвращающие объект, являющийся ORM-сопоставленнымInstrumentedAttribute
, а не явноColumnElement
, не могли быть корректно обработаны при передаче выражения вSession.query()
. Логика в 0.9 оказалась успешной, поэтому данный вариант использования теперь поддерживается.References: #3448
sql¶
Исправлена ошибка, при которой адаптация клаузулы к объекту
Label
не могла во всех случаях учесть помеченное SQL-выражение, в результате чего любая SQL-операция, использующаяLabel.self_group()
, использовала исходное неадаптированное выражение. Одним из следствий этого может быть то, что ORM-конструкцияaliased()
будет не полностью вмещать атрибуты, отображаемыеcolumn_property
, в результате чего при использовании свойства в некоторых видах SQL-сравнений может произойти утечка данных из неадаптированной таблицы.References: #3445
postgresql¶
Добавлена поддержка параметров хранения в CREATE INDEX с использованием нового ключевого слова-аргумента
postgresql_with
. Также добавлена поддержка отражения для поддержки как флагаpostgresql_with
, так и флагаpostgresql_using
, которые теперь будут устанавливаться на отражаемых объектахIndex
, а также присутствовать в новом словаре «dialect_options» в результате работыInspector.get_indexes()
. Pull request любезно предоставлен Питом Холлобоном.См.также
References: #3455
Добавлена новая опция выполнения
max_row_buffer
, которая интерпретируется диалектом psycopg2 при использовании опцииstream_results
, задающей ограничение на размер выделяемого буфера строк. Это значение также предоставляется на основе целочисленного значения, передаваемого вQuery.yield_per()
. Pull request courtesy mcclurem.Исправлена проблема, впервые появившаяся в версии 1.0.5, для повторного исправления поддержки JSONB в psycopg2cffi, так как в версии 2.7.1 они неожиданно включили безусловное декодирование типов JSONB. Определение версии теперь указывает на версию 2.7.1 как на ту, в которой мы должны ожидать, что DBAPI будет выполнять кодирование json.
References: #3439
Исправлена конструкция
ExcludeConstraint
для поддержки общих возможностей, которые теперь есть у других объектов типаIndex
, а именно: выражение столбца может быть указано как произвольное SQL-выражение, такое какcast
илиtext
.References: #3454
mssql¶
Исправлена проблема, связанная с использованием типа
VARBINARY
в сочетании с INSERT из NULL + pyodbc; pyodbc требует передачи специального объекта для сохранения NULL. Поскольку типVARBINARY
теперь обычно используется по умолчанию дляLargeBinary
из-за #3039, эта проблема частично является регрессией в версии 1.0. Драйвер pymssql, по-видимому, не затронут.References: #3464
misc¶
Исправлена внутренняя процедура «мемоизации» для типов методов, в результате чего дескриптор Python больше не используется; исправлена проверяемость этих методов, включая поддержку документации Sphinx.
References: #2077
1.0.5¶
Released: June 7, 2015orm¶
Добавлено новое событие
InstanceEvents.refresh_flush()
, вызываемое, когда в процессе промывки вызывается значение по умолчанию уровня INSERT или UPDATE, полученное через RETURNING или по умолчанию на стороне Python. Это сделано для того, чтобы обеспечить крючок, который больше не присутствует в результате использования #3167, когда события атрибутов и проверки больше не вызываются в процессе flush.References: #3427
Легкий именованный кортеж», используемый, когда
Query
возвращает строки, не смог корректно реализовать__slots__
, в результате чего он по-прежнему имел__dict__
. Это решено, но в крайне маловероятном случае, если кто-то присваивал значения возвращаемым кортежам, это больше не будет работать.References: #3420
engine¶
Добавлено новое событие движка
ConnectionEvents.engine_disposed()
. Вызывается после вызова методаEngine.dispose()
.Внесены изменения в хук плагина движка, в результате которых метод
URL.get_dialect()
будет продолжать возвращать конечный объектDialect
при использовании плагина диалекта, при этом вызывающему пользователю не нужно будет знать о методеDialect.get_dialect_cls()
.References: #3379
Исправлена ошибка, при которой некорректно разбирались известные булевы значения, используемые
engine_from_config()
; к ним относилисьpool_threadlocal
и аргумент psycopg2use_native_unicode
.References: #3435
Добавлена поддержка случая, когда в неправильном DBAPI имена исключений pep-249 привязаны к классам исключений с совершенно другими именами, что не позволяет собственному обертыванию исключений SQLAlchemy соответствующим образом обернуть ошибку. Для поддержки этой возможности используемый диалект SQLAlchemy должен реализовать новый аксессор
DefaultDialect.dbapi_exception_translation_map
; сейчас это реализовано для диалекта py-postgresql.References: #3421
Исправлена ошибка, связанная с тем, что при использовании обработчиков событий проверки пула и неудачных попытках подключения в самом обработчике, принадлежащая ему запись соединения не освобождалась до тех пор, пока не освобождалась стековая трассировка самой ошибки подключения. Для случая, когда используется тестовый пул, состоящий только из одного соединения, это означает, что пул будет полностью проверен до тех пор, пока не будет освобожден этот стек-трассировщик. Это в основном влияет на очень специфические сценарии отладки и вряд ли будет заметно в производственном приложении. Исправление применяет явную проверку записи перед повторным вызовом пойманного исключения.
References: #3419
sql¶
Добавлена официальная поддержка CTE, используемого SELECT, присутствующим внутри
Insert.from_select()
. Такое поведение случайно работало до версии 0.9.9, когда оно перестало работать из-за не связанных с этим изменений в составе #3248. Заметим, что в данном случае предложение WITH отображается после INSERT и перед SELECT; полная функциональность CTE, отображаемых на верхнем уровне INSERT, UPDATE, DELETE, - это новая возможность, которая будет реализована в более позднем выпуске.This change is also backported to: 0.9.10
References: #3418
postgresql¶
Исправлены некоторые проблемы с типизацией и тестированием диалекта pypy psycopg2cffi, в частности то, что в текущей версии 2.7.0 отсутствует встроенная поддержка типа JSONB. Определение версии для функций psycopg2 было настроено на специальную подверсию для psycopg2cffi. Кроме того, включено тестовое покрытие для всей серии функций psycopg2 под psycopg2cffi.
References: #3439
mssql¶
В диалект MSSQL добавлен новый флаг диалекта
legacy_schema_aliasing
, который при установке значения False отключает очень старое и устаревшее поведение, заключающееся в попытке компилятора превратить все имена таблиц с критериями схемы в имена псевдонимов для решения старых и уже не локализуемых проблем, когда SQL-сервер не мог разобрать многокомпонентное имя идентификатора при любых обстоятельствах. Такое поведение препятствовало корректной работе более сложных операторов, включая те, которые используют подсказки, а также CRUD-операторов, в которые встроены коррелированные операторы SELECT. Вместо того чтобы продолжать исправлять эту функцию для работы с более сложными операторами, лучше просто отключить ее, поскольку она больше не нужна ни в одной современной версии SQL-сервера. Флаг по умолчанию принимает значение True для серии 1.0.x, оставляя текущее поведение неизменным для этой серии версий. В серии 1.1 по умолчанию будет установлено значение False. Для серии 1.0, если ни одно из значений не установлено явно, при первом использовании в операторе таблицы с квалификацией схемы выдается предупреждение, что предполагает установку флага в значение False для всех современных версий SQL Server.См.также
misc¶
Добавлена поддержка передачи
*args
в начальный вызываемый модуль запроса baked, аналогично тому, как*args
поддерживается для методовBakedQuery.add_criteria()
иBakedQuery.with_criteria()
. Первоначальный PR любезно предоставлен Naoki INADA.В
MutableBase
MutableBase._get_listen_keys()
добавлен новый полупубличный метод. Переопределение этого метода необходимо в том случае, если подклассуMutableBase
нужно, чтобы при перехвате событийInstanceEvents.refresh()
илиInstanceEvents.refresh_flush()
распространялись события для ключей атрибутов, отличных от ключа, с которым связан мутабельный тип. В качестве примера можно привести композиты, использующиеMutableComposite
.References: #3427
Исправлена регрессия в расширении
sqlalchemy.ext.mutable
, возникшая в результате исправления ошибки #3167, когда события атрибутов и валидации больше не вызывались в процессе flush. Расширение mutable полагалось на такое поведение в случае, когда за генерацию нового значения при INSERT или UPDATE отвечал Python-уровень столбца по умолчанию, или когда значение извлекалось из предложения RETURNING для режима «eager defaults». При этом новое значение не будет подвержено какому-либо событию, и мутабельное расширение не сможет установить правильное принуждение или прослушивание истории. Добавлено новое событиеInstanceEvents.refresh_flush()
, которое теперь используется в mutable-расширении для этого случая.References: #3427
1.0.4¶
Released: May 7, 2015orm¶
Исправлена регрессия, связанная с непредвиденным использованием, когда в странном случае, когда первичное соединение отношения включало сравнение с нехешируемым типом, таким как HSTORE, ленивая загрузка не выполнялась из-за хеш-ориентированной проверки параметров оператора, измененной в 1.0 в результате #3061 на использование хеширования и измененной в #3368 на выполнение в случаях более распространенных, чем «load on pending». Теперь значения предварительно проверяются на наличие атрибута
__hash__
.References: #3416
Либерализовано утверждение, добавленное в #3347 для защиты от неизвестных условий при сращивании внутренних соединений внутри объединенных eager-нагрузок с помощью
innerjoin=True
; если некоторые из соединений используют «вторичную» таблицу, то для прохождения утверждения необходимо развернуть дальнейшие соединения.Исправлены / добавлены в тесты еще несколько выражений, которые были признаны неудачными при добавлении нового значения ключа „entity“ в
Query.column_descriptions
, логика обнаружения выражения «from» снова переработана для учета столбцов из псевдоклассов, а также для сообщения правильного значения флага «aliased» в этих случаях.
schema¶
Исправлена ошибка в улучшенной логике присоединения ограничений, введенная в #3341, когда в необычном случае, когда ограничение ссылается на смесь объектов
Column
и строковых имен столбцов одновременно, логика автоматического присоединения к столбцам будет пропущена; чтобы ограничение было автоприсоединено в этом случае, все столбцы должны быть собраны в целевой таблице заранее. В документ по миграции добавлен новый раздел, посвященный первоначальной функции, а также данному изменению.References: #3411
tests¶
Исправлен импорт, не позволявший корректно работать с файлом «pypy setup.py test».
This change is also backported to: 0.9.10
References: #3406
misc¶
Исправлена ошибка, из-за которой при использовании расширенной системы инструментария атрибутов не возникало корректное исключение, когда
class_mapper()
вызывался с недопустимым входом, который также не являлся слабоссылаемым, например, целым числом.This change is also backported to: 0.9.10
References: #3408
1.0.3¶
Released: April 30, 2015orm¶
Исправлена регрессия из 0.9.10 до релиза, связанная с #3349, когда проверка состояния запроса на
Query.update()
илиQuery.delete()
сравнивала пустой кортеж с самим собой с помощьюis
, что на PyPy приводило к ошибкеTrue
в этом случае; это ошибочно выдавало предупреждение в 0.9 и вызывало исключение в 1.0.References: #3405
Исправлена ошибка из версии 0.9.10 до релиза, при которой добавление
entity
к аксессоруQuery.column_descriptions
приводило к ошибке, если целевая сущность создавалась из core selectable, например, объектаTable
илиCTE
.Исправлена регрессия в процессе промывки, когда атрибут устанавливался в SQL-выражение для UPDATE, а SQL-выражение при сравнении с предыдущим значением атрибута выдавало SQL-сопоставление, отличное от
==
или!=
, то возникало исключение «Boolean value of this clause is not defined». Исправление гарантирует, что блок работы не будет интерпретировать SQL-выражение подобным образом.References: #3402
Исправлена неожиданная регрессия использования #2992, когда текстовые элементы, помещенные в предложение
Query.order_by()
в сочетании с объединенной ускоренной загрузкой, добавлялись в предложение columns внутреннего запроса таким образом, что принимались за имена столбцов, привязанных к таблице, в случае, когда объединенная ускоренная загрузка должна обернуть запрос в подзапрос для учета ограничения/смещения.Изначально такое поведение было намеренным, поскольку запрос типа
query(User).order_by('name').limit(1)
будет упорядочиваться поuser.name
даже в том случае, если запрос будет модифицирован за счет присоединенной ускоренной загрузки и окажется внутри подзапроса, поскольку'name'
будет интерпретироваться как символ, который должен находиться внутри предложения FROM, в данном случаеUser.name
, который затем будет скопирован в предложение columns, чтобы обеспечить его присутствие для ORDER BY. Однако эта функция не позволяет предусмотреть случай, когдаorder_by("name")
ссылается на конкретное имя метки, уже присутствующее в локальном предложении columns, а не на имя, связанное с selectable в предложении FROM.Кроме того, функция также не справляется с устаревшими случаями, такими как
order_by("name desc")
, которые, хотя и выдают предупреждение о том, что здесь следует использоватьtext()
(отметим, что эта проблема не затрагивает случаи, когдаtext()
используется явно), все же дают запрос, отличный от предыдущего, где выражение «name desc» копируется в предложение columns неуместным образом. Решение проблемы заключается в том, что функция «объединенной ускоренной загрузки» будет пропускать эти так называемые выражения «ссылки на метку» при дополнении внутреннего предложения columns, как если бы они уже были конструкциямиtext()
.References: #3392
Исправлена регрессия, связанная с событием
MapperEvents.instrument_class()
, когда его вызов переносился на время после инструментации класса менеджером класса, что прямо противоположно тому, что указано в документации к событию. Обоснованием такого перехода послужило то, что в Declarative для использования новых возможностей@declared_attr
, описанных в Улучшения в декларативных миксинах, @declared_attr и связанных с ними функциях, был сделан шаг по настройке полного «менеджера инструментария» для класса до его отображения, но также это изменение было сделано вопреки классическому использованиюMapper
для согласованности. Тем не менее, SQLSoup полагается на то, что при классическом отображении событие инструментации произойдет раньше, чем любая инструментация. Это поведение возвращается в случае классического и декларативного отображения, причем последнее реализовано с помощью простой мемоизации без использования менеджера классов.References: #3388
Исправлена проблема в событии new
QueryEvents.before_compile()
, когда изменения, внесенные в коллекцию сущностей объектаQuery
для загрузки в рамках события, отображались в SQL, но не отражались в процессе загрузки.References: #3387
engine¶
Добавлены новые возможности для поддержки плагинов движка/пула с расширенной функциональностью. В пул соединений добавлена новая функция «мягкого аннулирования» на уровне обертки проверяемого соединения, а также
_ConnectionRecord
. Это работает аналогично современному аннулированию пула, когда соединения не закрываются активно, а утилизируются только при следующей проверке; по сути, это версия этой функции для каждого соединения. В дополнение к этому добавлено новое событиеPoolEvents.soft_invalidate()
.Также добавлен новый флаг
ExceptionContext.invalidate_pool_on_disconnect
. Позволяет обработчику ошибок в рамкахConnectionEvents.handle_error()
поддерживать состояние «разъединения», но обрабатывать вызов invalidate на отдельных соединениях определенным образом в рамках события.References: #3379
Добавлено новое событие
do_connect
, которое позволяет перехватывать/заменять момент вызова хукаDialect.connect()
для создания DBAPI-соединения. Также добавлены хукиDialect.get_dialect_cls()
иDialect.engine_created()
, позволяющие внешним плагинам добавлять события в существующие диалекты, используя точки входа.References: #3355
sql¶
Добавлен метод-заместитель
TypeEngine.compare_against_backend()
, который теперь используется миграциями Alembic, начиная с версии 0.7.6. Определяемые пользователем типы могут использовать этот метод для сравнения типа с типом, отраженным из базы данных.Исправлена ошибка, при которой усечение длинных меток в SQL могло приводить к появлению метки, перекрывающей другую метку, не усеченную; это происходило из-за того, что порог длины для усечения был больше, чем часть метки, остающаяся после усечения. Теперь эти два значения стали одинаковыми: label_length - 6. В результате более короткие метки столбцов будут «усечены» там, где раньше они не были бы усечены.
References: #3396
Исправлена регрессия, связанная с #3282, когда коллекция
tables
, передаваемая в качестве аргумента ключевого слова событиямDDLEvents.before_create()
,DDLEvents.after_create()
,DDLEvents.before_drop()
иDDLEvents.after_drop()
, представляла собой уже не список таблиц, а список кортежей, содержащий вторую запись с внешними ключами, которые необходимо добавить или удалить. Поскольку коллекцияtables
, хотя и документирована как не всегда стабильная, но на нее можно положиться, это изменение считается регрессом. Кроме того, в некоторых случаях для операции «drop» эта коллекция представляла собой итератор, который при преждевременном итерировании приводил к неудаче операции. Теперь во всех случаях коллекция представляет собой список объектов таблицы, и добавлено тестовое покрытие для формата этой коллекции.References: #3391
misc¶
Исправлена ошибка в ассоциативном прокси, когда при сравнении атрибута relationship->scalar с необъектным атрибутом any()/has() происходил сбой, например,
filter(Parent.some_collection_to_attribute.any(Child.attr == 'foo'))
.References: #3397
1.0.2¶
Released: April 24, 2015orm declarative¶
Исправлена неожиданная регрессия использования декларативных аксессоров
__declare_first__
и__declare_last__
, когда они переставали вызываться на суперклассе декларативной базы.References: #3383
sql¶
Исправлена регрессия, которая была ошибочно исправлена в версии 1.0.0b4 (в результате чего стало две регрессии); сообщения о том, что операторы SELECT выполняли GROUP BY по имени метки и терпели неудачу, были ошибочно истолкованы как то, что некоторые бэкенды, такие как SQL Server, вообще не должны выдавать ORDER BY или GROUP BY по простому имени метки; на самом деле мы забыли, что 0. 9 уже выдавал ORDER BY по простому имени метки для всех бэкендов, как описано в Конструкции меток теперь могут отображаться только в виде своего имени в ORDER BY, хотя в 1.0 эта логика была переписана в #2992. Что касается выдачи GROUP BY по простой метке, то даже в PostgreSQL есть случаи, когда она выдает ошибку, хотя метка, по которой нужно группировать, должна быть очевидной, поэтому очевидно, что GROUP BY никогда не должна выдаваться таким образом автоматически.
В версии 1.0.2 SQL Server, Firebird и другие бэкенды снова будут выдавать ORDER BY по простому имени метки при передаче конструкции
Label
, которая также присутствует в предложении columns. Кроме того, ни один бэкенд не будет выдавать GROUP BY по имени простой метки только при передаче конструкцииLabel
.
1.0.1¶
Released: April 23, 2015orm¶
Исправлена проблема, при которой запрос вида
query(B).filter(B.a != A(id=7))
приводил к появлению символаNEVER_SET
, если задавался переходный объект. Для постоянного объекта всегда использовалось сохраняемое значение базы данных, а не текущее установленное значение. При условии, что включена автопромывка, для постоянных значений это обычно не заметно, так как все ожидающие изменения в любом случае будут промыты первыми. Однако это противоречит логике, используемой для неотрицательного сравненияquery(B).filter(B.a == A(id=7))
, которое использует текущее значение и дополнительно позволяет сравнивать с переходными объектами. Теперь при сравнении используется текущее значение, а не значение, хранящееся в базе данных.В отличие от других проблем
NEVER_SET
, которые в этом выпуске исправляются как регрессии, вызванные #3061, данная проблема присутствует как минимум в версии 0.8, а возможно, и раньше, однако она была обнаружена в результате исправления связанных с ней проблемNEVER_SET
.References: #3374
Исправлена регрессия неожиданного использования, вызванная оператором #3061, когда символ NEVER_SET мог просочиться в запросы, ориентированные на отношения, включая запросы
filter()
иwith_parent()
. СимволNone
возвращается во всех случаях, однако многие из этих запросов никогда не поддерживались корректно в любом случае и выдают сравнения с NULL без использования оператора IS. По этой причине предупреждение добавляется и для того подмножества запросов отношений, в которых в настоящее время не предусмотрено использованиеIS NULL
.References: #3371
Исправлена регрессия, вызванная #3061, при которой символ NEVER_SET мог просочиться в запрос lazyload, после того как произошла очистка отложенного объекта. Это происходило, как правило, в отношениях «многие-к-одному», не использующих простую стратегию «get». Хорошей новостью является то, что исправление повышает эффективность по сравнению с 0.9, поскольку теперь мы можем полностью пропустить оператор SELECT при обнаружении символов NEVER_SET в параметрах; до #3061 мы не могли определить, установлен ли здесь None или нет.
References: #3368
engine¶
В качестве синонима параметра
None
добавлено строковое значение"none"
, принимаемое параметромPool.reset_on_return
, так что строковые значения могут использоваться для всех параметров, что позволяет без проблем использовать утилиты типаengine_from_config()
.This change is also backported to: 0.9.10
References: #3375
sql¶
Исправлена проблема, при которой прямой запрос SELECT EXISTS не присваивал отображению результатов правильный тип результата Boolean, и вместо этого в карту результатов просачивались типы столбцов из запроса. Эта проблема существует и в 0.9 и более ранних версиях, однако в этих версиях она менее заметна. В версии 1.0, в связи с появлением #918, это становится регрессией, поскольку теперь мы полагаемся на то, что отображение результатов будет очень точным, иначе мы можем назначить процессоры типа результата не тому столбцу. Во всех версиях эта проблема также приводит к тому, что простой EXISTS не применяет обработчик типа Boolean, что приводит к простым значениям 1/0 для бэкендов, не имеющих собственных boolean, вместо True/False. Исправление заключается в том, что аргумент EXISTS columns будет анонсирован, как и другие колоночные выражения; аналогичное исправление реализовано для чисто булевых выражений типа
not_(True())
.References: #3372
sqlite¶
Исправлена регрессия, связанная с #3282, когда из-за того, что мы пытаемся предположить наличие ALTER при создании/удалении схем, в случае SQLite мы просто говорили, что при создании и удалении таблиц не нужно беспокоиться о внешних ключах, поскольку ALTER недоступен. Это означает, что сортировка таблиц в случае SQLite практически отсутствует, а для подавляющего большинства случаев использования SQLite это не является проблемой.
Однако пользователи, выполняющие DROP на SQLite с таблицами, содержащими данные, и с включенной ссылочной целостностью, будут сталкиваться с ошибками, так как сортировка зависимостей * имеет значение* в случае DROP с принудительными ограничениями, когда в этих таблицах есть данные (SQLite по-прежнему с удовольствием позволяет создавать внешние ключи к несуществующим таблицам и сбрасывать таблицы, ссылающиеся на существующие, с включенными ограничениями, если в них нет данных, на которые ссылаются).
Для того чтобы сохранить новую возможность #3282 и в то же время позволить операции SQLite DROP поддерживать упорядочивание, мы теперь выполняем сортировку с учетом полных FK, и если встречаем неразрешимый цикл, то только тогда мы отказываемся от попытки сортировки таблиц; вместо этого мы выдаем предупреждение и переходим к несортированному списку. Если среда нуждается в упорядоченных DROPах и имеет циклы внешних ключей, то в предупреждении указывается, что необходимо восстановить флаг
use_alter
для объектовForeignKey
иForeignKeyConstraint
, чтобы только эти объекты были опущены из сортировки зависимостей.См.также
Флаг use_alter на ForeignKeyConstraint (обычно) больше не нужен - содержит обновленную заметку о SQLite.
References: #3378
misc¶
Исправлена регрессия, связанная с #3034, при которой клаузулы limit/offset неправильно интерпретировались диалектом Firebird. Pull request courtesy effem-git.
References: #3380
Исправлена поддержка режима «literal_binds» при использовании limit/offset с Firebird, так что значения снова выводятся в строку при выборе этого режима. Связано с #3034.
References: #3381
1.0.0¶
Released: April 16, 2015orm¶
Добавлен новый аргумент
Query.update.update_args
, который позволяет передавать kw-аргументы, такие какmysql_limit
, в базовую конструкциюUpdate
. Pull request любезно предоставлен Amir Sadoughi.Выявлено несоответствие при работе с
Query.join()
к одной и той же цели более одного раза; неявное вычитание происходит только в случае соединения отношений, а благодаря #3233 в версии 1.0 соединение к одной и той же таблице дважды ведет себя иначе, чем в версии 0.9, поскольку больше не производит ошибочного псевдонима. Чтобы помочь документировать это изменение, в примечаниях к миграции была обобщена формулировка, касающаяся #3233, и добавлено предупреждение, когдаQuery.join()
вызывается по отношению к одному и тому же целевому отношению более одного раза.References: #3367
Внесено небольшое улучшение в эвристику отношений при определении удаленной стороны с полусамостоятельными (например, два объединенных подкласса inh ссылаются друг на друга), не простыми условиями присоединения, так как учитывается parententity и уменьшается необходимость использования аннотации
remote()
; это может восстановить некоторые случаи, которые до версии 0.9.4 могли работать без аннотации через #2948.References: #3364
sql¶
Топологическая сортировка, используемая для сортировки объектов
Table
и доступная через коллекциюMetaData.sorted_tables
, теперь будет производить детерминированное упорядочивание, т.е. одинаковое упорядочивание каждый раз при задании набора таблиц с определенными именами и зависимостями. Это необходимо для сравнения DDL-скриптов и других случаев использования. Таблицы передаются в топологическую сортировку отсортированными по именам, а сама топологическая сортировка будет обрабатывать поступающие данные в упорядоченном виде. Pull request любезно предоставлен Себастьяном Банком.References: #3084
Исправлена проблема, при которой объект
MetaData
, использующий соглашение об именовании, не мог корректно работать с pickle. Атрибут пропускался, что приводило к несоответствиям и сбоям, если непикированный объектMetaData
использовался для создания дополнительных таблиц.This change is also backported to: 0.9.10
References: #3362
postgresql¶
Исправлена давняя ошибка, из-за которой тип
Enum
, используемый в диалекте psycopg2 в сочетании с неаскриптивными значениями иnative_enum=False
, не мог правильно декодировать возвращаемые результаты. Это было связано с тем, что тип PGENUM
раньше был отдельным типом без опции «non native».This change is also backported to: 0.9.10
References: #3354
mssql¶
Исправлена ошибка, при которой механика «last inserted id» не сохраняла правильное значение для MSSQL при INSERT, когда значение первичного ключа присутствовало в параметрах вставки перед выполнением, а также в случае, когда при INSERT из SELECT целевые колонки указывались как объекты колонок, а не как строковые ключи.
References: #3360
Использование конструктора
Binary
, который теперь присутствует в pymssql, вместо того, чтобы добавлять его. Pull request любезно предоставлен Рамиро Моралесом.
tests¶
Исправлены пути, используемые при запуске тестов; для sqla_nose.py и py.test префикс «./lib» снова вставляется в начало sys.path, но только если не установлен флаг sys.flags.no_user_site; это делает его похожим на то, как Python по умолчанию ставит «.» в текущий путь. Для tox мы теперь устанавливаем флаг PYTHONNOUSERSITE.
References: #3356
1.0.0b5¶
Released: April 3, 2015orm¶
Исправлена ошибка, из-за которой при отслеживании состояния в нескольких вложенных операциях
Session.begin_nested()
не передавался флаг «грязный» для объекта, который был обновлен во внутренней точке сохранения, в результате чего при откате вложенной точки сохранения объект не попадал в состояние, срок действия которого истек, и возвращался к состоянию базы данных.This change is also backported to: 0.9.10
References: #3352
Query
не поддерживает объединения, подселекты или специальные предложения FROM при использовании методовQuery.update()
илиQuery.delete()
; вместо того чтобы молча игнорировать эти поля, если были вызваны методы типаQuery.join()
илиQuery.select_from()
, выдается ошибка. В версии 0.9.10 при этом выдается только предупреждение.References: #3349
Добавлен вызов list() вокруг слабого словаря, используемого на этапе фиксации сессии, который без него мог привести к ошибке «dictionary changed size during iter» при взаимодействии со сборкой мусора в процессе. Изменение было внесено в #3139.
Исправлена ошибка, связанная с «вложенной» внутренней загрузкой, которая существует и в 0.9, но в 1.0 является скорее регрессией из-за #3008, включающей «вложенность» по умолчанию. Таким образом, объединенная загрузка, проходящая через пути сиблингов от общего предка с использованием innerjoin=True, будет корректно вставлять каждый сиблинг «innerjoin» в соответствующую часть соединения, когда серии внутренних/внешних соединений смешиваются вместе.
References: #3347
sql¶
Предупреждение, выдаваемое типом unicode для неюникодного типа, было либерализовано, чтобы предупреждать о значениях, которые даже не являются строковыми, например, целых числах; ранее обновленная система предупреждений в версии 1.0 использовала операции форматирования строк, что приводило к внутренней ошибке TypeError. Хотя в идеале эти случаи должны вызывать абсолютную ошибку, некоторые бэкенды, такие как SQLite и MySQL, принимают их и потенциально могут использоваться в устаревшем коде, не говоря уже о том, что они всегда будут проходить, если преобразование юникода отключено для целевого бэкенда.
References: #3346
postgresql¶
1.0.0b4¶
Released: March 29, 2015sql¶
Исправлена ошибка в новой функции «разрешения меток» #2992, когда метка, которая была анонимной, а затем снова была помечена именем, не могла быть найдена через текстовую метку. Такая ситуация возникает естественным образом, когда сопоставленному
column_property()
в запросе задается явная метка.References: #3340
Исправлена ошибка в новой функции #2992 «разрешение меток», когда строковая метка, помещенная в order_by() или group_by() оператора, отдавала приоритет имени, находящемуся в предложении FROM, а не более локально доступному имени в предложении columns.
References: #3335
schema¶
Функция «автоприсоединения» таких ограничений, как
UniqueConstraint
иCheckConstraint
, была усовершенствована: когда ограничение связано с объектамиColumn
, не связанными с таблицей, оно будет устанавливать слушателей событий на сами столбцы, так что ограничение автоматически присоединяется в то же время, когда столбцы связаны с таблицей. Это, в частности, помогает в некоторых крайних случаях в декларативном методе, но может быть использовано и в общем случае.References: #3341
mysql¶
Исправлена поддержка юникода для PyMySQL при использовании операции «executemany» с юникодными параметрами. Теперь SQLAlchemy передает как оператор, так и связанные параметры в виде юникодных объектов, поскольку PyMySQL обычно использует внутреннюю интерполяцию строк для создания конечного оператора, а в случае executemany выполняет шаг «кодирования» только для конечного оператора.
This change is also backported to: 0.9.10
References: #3337
mssql¶
Отключен флаг «simple order by» в диалектах MSSQL и Oracle; это флаг, который при использовании #2992 приводит к тому, что выражение order by или group by, которое также находится в предложении columns, копируется по метке, даже если на него ссылаются как на объект выражения. Для MSSQL теперь используется старое поведение, при котором по умолчанию копируется все выражение целиком, поскольку MSSQL может быть придирчивым к таким выражениям, особенно в выражениях GROUP BY. Флаг также отключен для диалектов Firebird и Sybase.
Примечание
данное решение было некорректным, переделка данного решения приведена в версии 1.0.2.
References: #3338
1.0.0b3¶
Released: March 20, 2015mysql¶
Исправлен коммит для выпуска #2771, который был случайно закомментирован.
References: #2771
1.0.0b2¶
Released: March 20, 2015orm¶
Исправлена неожиданная регрессия использования из pullreq github:137, когда юникодные литералы Py2K (например,
u""
) не принимались опциейrelationship.cascade
. Pull request любезно предоставлен Julien Castets.References: #3327
orm declarative¶
Ослаблены некоторые ограничения, накладываемые на объекты
@declared_attr
, которые не позволяли вызывать их вне декларативного процесса; это связано с улучшениями из #3150, позволяющими@declared_attr
возвращать значение, кэшируемое на основе текущего класса в процессе его конфигурирования. Исключение raise было удалено, а поведение изменено таким образом, что вне декларативного процесса функция, оформленная@declared_attr
, вызывается каждый раз как обычная@property
, без использования кэширования, так как на данном этапе оно отсутствует.References: #3331
engine¶
»Автозакрытие» для
ResultProxy
теперь является «мягким» закрытием. То есть после исчерпания всех строк с помощью методов выборки курсор DBAPI освобождается, как и раньше, и объект можно смело выбрасывать, но методы выборки можно продолжать вызывать, для чего они будут возвращать объект конца результата (None для fetchone, пустой список для fetchmany и fetchall). Только при явном вызовеResultProxy.close()
эти методы выдадут ошибку «результат закрыт».
mysql¶
Исправлен тип
BIT
на Py3K, который некорректно использовал функциюord()
. Pull request любезно предоставлен Дэвидом Марином.This change is also backported to: 0.9.10
References: #3333
Исправления для полной поддержки использования специфического для MySQL набора символов
'utf8mb4'
в диалектах MySQL, в частности, MySQL-Python и PyMySQL. Кроме того, базы данных MySQL, сообщающие о более необычных наборах символов, таких как „koi8u“ или „eucjpms“, также будут работать корректно. Pull request любезно предоставлен Томасом Грейнджером.References: #2771
1.0.0b1¶
Released: March 13, 2015Версия 1.0.0b1 является первым выпуском серии 1.0. Многие изменения, описанные здесь, присутствуют также в серии 0.9, а иногда и 0.8. Изменения, характерные для версии 1.0 и связанные с проблемами совместимости, приведены в разделе Что нового в SQLAlchemy 1.0?.
general¶
Улучшено использование структурной памяти за счет более значительного использования
__slots__
для многих внутренних объектов. Эта оптимизация особенно ориентирована на базовый объем памяти больших приложений, имеющих большое количество таблиц и столбцов, и значительно уменьшает объем памяти для целого ряда объектов с большим объемом памяти, включая внутреннюю память прослушивания событий, объекты компараторов и части системы атрибутов и стратегий загрузчика ORM.Атрибут
__module__
теперь устанавливается для всех тех SQL- и ORM-функций, которые получены в виде символов «public factory», что должно помочь средствам документирования составлять отчеты о целевом модуле.References: #3218
orm¶
В словари, возвращаемые выражением
Query.column_descriptions
, добавлена новая запись"entity"
. Она относится к первичному отображаемому классу ORM или псевдоклассу, на который ссылается выражение. По сравнению с существующей записью для"type"
, это всегда будет сопоставленная сущность, даже если она извлечена из столбцового выражения, или None, если данное выражение является чистым выражением ядра. См. также #3403, в котором исправлена регрессия в этой функции, которая не была выпущена в версии 0.9.10, но была выпущена в версии 1.0.This change is also backported to: 0.9.10
References: #3320
Добавлен новый параметр
Session.connection.execution_options
, который может быть использован для настройки параметров выполнения соединенияConnection
при его первой проверке, до начала транзакции. Это используется для настройки таких параметров, как уровень изоляции соединения перед началом транзакции.См.также
Настройка уровней изоляции транзакций / DBAPI AUTOCOMMIT - новый раздел документации, в котором подробно описаны лучшие практики настройки изоляции транзакций с помощью сессий.
This change is also backported to: 0.9.9
References: #3296
Добавлен новый метод
Session.invalidate()
, функционирующий аналогичноSession.close()
, за исключением вызоваConnection.invalidate()
для всех соединений, гарантирующего, что они не будут возвращены в пул соединений. Это полезно в ситуациях, например, при работе с таймаутами gevent, когда дальнейшее использование соединения небезопасно, даже для отката.This change is also backported to: 0.9.9
Модель «primaryjoin» была несколько расширена, чтобы позволить условие объединения, которое строго от одного столбца к самому себе, транслируется через некоторую функцию или выражение SQL. Это своего рода эксперимент, но первым доказательством концепции является условие присоединения «материализованного пути», в котором строка пути сравнивается сама с собой с помощью оператора «like». Оператор
ColumnOperators.like()
также был добавлен в список допустимых операторов для использования в условии первичного соединения.This change is also backported to: 0.9.5
References: #3029
Добавлена новая служебная функция
make_transient_to_detached()
, которая может быть использована для создания объектов, которые ведут себя так, как будто они были загружены из сессии, а затем отсоединены. Атрибуты, которые отсутствуют, помечаются как истекшие, и объект может быть добавлен в сессию, где он будет вести себя как постоянный.This change is also backported to: 0.9.5
References: #3017
Добавлен новый набор событий
QueryEvents
. СобытиеQueryEvents.before_compile()
позволяет создавать функции, которые могут вносить дополнительные модификации в объектыQuery
перед построением оператора SELECT. Предполагается, что это событие станет гораздо более полезным с появлением новой системы проверки, которая позволит производить детальные модификации объектовQuery
в автоматическом режиме.См.также
References: #3317
Обертывание подзапросов, возникающее при использовании объединенной ускоренной загрузки в запросах типа «один ко многим», в которых также используются LIMIT, OFFSET или DISTINCT, отключено в случае отношений «один к одному», то есть «один к многим», для которых значение
relationship.uselist
установлено в False. Это позволит получить более эффективные запросы в таких случаях.References: #3249
Внутреннее устройство отображаемых состояний было переработано, что позволило на 50% сократить количество вызовов, связанных с «истечением срока действия» объектов, как в функции «auto expire» для
Session.commit()
и дляSession.expire_all()
, так и в шаге «cleanup», который происходит при сборке состояний объектов в мусор.References: #3307
Предупреждение выдается, когда одна и та же полиморфная идентичность назначается двум разным отображениям в одной иерархии. Обычно это является ошибкой пользователя и означает, что два различных типа отображения не могут быть корректно различимы во время загрузки. Pull request любезно предоставлен Sebastian Bank.
References: #3262
Создана новая серия методов
Session
, позволяющих подключаться непосредственно к средствам создания операторов INSERT и UPDATE. При правильном использовании эта экспертно-ориентированная система может позволить использовать ORM-сопоставления для генерации массовых операторов вставки и обновления, объединенных в группы executemany, что позволяет выполнять операции со скоростью, не уступающей прямому использованию ядра.См.также
References: #3100
Добавлен параметр
Query.join.isouter
, который является синонимом вызоваQuery.outerjoin()
; этот флаг призван обеспечить более согласованный интерфейс по сравнению с CoreFromClause.join()
. Pull request любезно предоставлен Джонатаном Ванаско (Jonathan Vanasco).References: #3217
Добавлены новые обработчики событий
AttributeEvents.init_collection()
иAttributeEvents.dispose_collection()
, которые отслеживают момент первого связывания коллекции с экземпляром и момент ее замены. Эти обработчики заменяют аннотациюcollection.linker()
. Старый обработчик по-прежнему поддерживается через адаптер событий.Метод
Query
вызовет исключение, еслиQuery.yield_per()
используется с отображениями или опциями, в которых будет происходить либо ускоренная загрузка подзапросов, либо объединенная ускоренная загрузка с коллекциями. Эти стратегии загрузки в настоящее время не совместимы с yield_per, поэтому, вызывая эту ошибку, метод становится более безопасным в использовании. Ускоренная загрузка может быть отключена с помощью опцииlazyload('*')
илиQuery.enable_eagerloads()
.Новая реализация
KeyedTuple
, используемая объектомQuery
, позволяет значительно повысить скорость при получении большого количества строк, ориентированных на столбцы.References: #3176
Поведение
joinedload.innerjoin
, а такжеrelationship.innerjoin
теперь заключается в использовании «вложенных» внутренних соединений, то есть вложенных справа, в качестве поведения по умолчанию, когда внутреннее соединение joined eager load цепляется к внешнему соединению eager load.References: #3008
Операции UPDATE теперь могут быть объединены в рамках ORM flush в более производительный вызов executemany(), аналогично тому, как могут быть объединены операторы INSERT; это будет происходить в рамках flush при условии, что последующие операторы UPDATE для того же отображения и таблицы будут включать одинаковые столбцы в предложении VALUES, что не будут встроены SQL-выражения уровня SET и что требования к версионности отображения совместимы с возможностью диалекта backend возвращать корректный счетчик строк для операции executemany.
В конструктор для
SynonymProperty
иComparableProperty
добавлен параметрinfo
.References: #2963
Коллекция
InspectionAttr.info
теперь перенесена вниз вInspectionAttr
, где помимо того, что она доступна для всех объектовMapperProperty
, она также теперь доступна для гибридных свойств, прокси ассоциаций, когда доступ к ним осуществляется черезMapper.all_orm_descriptors
.References: #2971
Сопоставленные атрибуты, помеченные как отложенные без явной отмены откладывания, теперь будут оставаться «отложенными», даже если их столбец каким-либо другим образом присутствует в наборе результатов. Это повышает производительность, поскольку ORM-загрузка больше не тратит время на поиск каждого отложенного столбца при получении набора результатов. Однако для приложений, которые полагались на это, теперь следует использовать явную опцию
undefer()
или аналогичную.Вызываемый модуль
proc()
, передаваемый методуcreate_row_processor()
пользовательских классовBundle
, теперь принимает только один аргумент «row».Удалены устаревшие крючки событий:
populate_instance
,create_instance
,translate_row
,append_result
Исправлена ошибка в ускоренной загрузке подзапросов, когда длинная цепочка ускоренных загрузок через границу полиморфный-подкласс в сочетании с полиморфной загрузкой не находила ссылку на подкласс в цепочке, выдавая ошибку с отсутствием имени свойства на
AliasedClass
.This change is also backported to: 0.9.5, 0.8.7
References: #3055
Исправлена ошибка ORM, когда функция
class_mapper()
маскировала ошибки AttributeErrors или KeyErrors, которые должны были возникать при конфигурировании маппера из-за ошибок пользователя. Перехват ошибок атрибутов/ключей стал более конкретным и не включает шаг конфигурирования.This change is also backported to: 0.9.5, 0.8.7
References: #3047
Исправлена ошибка в объектных сравнениях ORM, когда сравнение многие-к-одному
!= None
приводило к ошибке, если источником являлся алиасированный класс или если в запросе требовалось применить специальное алиасирование к выражению из-за алиасированных объединений или полиморфного запроса; также исправлена ошибка, когда сравнение многие-к-одному с состоянием объекта приводило к ошибке, если в запросе требовалось применить специальное алиасирование из-за алиасированных объединений или полиморфного запроса.This change is also backported to: 0.9.9
References: #3310
Исправлена ошибка, при которой внутреннее утверждение не выполнялось в случае, когда обработчик
after_rollback()
дляSession
некорректно добавляет состояние к этомуSession
внутри обработчика, а задание на предупреждение и удаление этого состояния (установленное #2389) пытается продолжить работу.This change is also backported to: 0.9.9
References: #3309
Исправлена ошибка, когда при вызове
Query.join()
с неизвестными аргументами kw возникала собственная ошибка TypeError, связанная с нарушением форматирования. Pull request любезно предоставлен Malthe Borch.This change is also backported to: 0.9.9
Исправлена ошибка в конструкции SQL с ленивой загрузкой, из-за которой сложное первичное соединение, многократно ссылающееся на один и тот же «локальный» столбец в стиле самореферентного соединения «столбец, указывающий на себя», подставлялось не во всех случаях. Логика определения подстановок здесь была переработана и стала более открытой.
This change is also backported to: 0.9.9
References: #3300
Опции «подстановочного» загрузчика, в частности, опция
load_only()
, устанавливаемая для охвата всех атрибутов, не упомянутых явно, теперь учитывает суперклассы данной сущности, если эта сущность отображена с помощью наследования, так что имена атрибутов в суперклассах также не будут загружаться. Кроме того, колонка полиморфного дискриминатора безусловно включается в список, так же как и колонки первичного ключа, поэтому даже при установке load_only() полиморфная загрузка подтипов продолжает работать корректно.This change is also backported to: 0.9.9
References: #3287
Исправлена ошибка, из-за которой, если исключение возникало в начале
Query
до получения результатов, особенно когда процессоры строк не могут быть сформированы, курсор оставался открытым с ожиданием результатов и фактически не закрывался. Обычно это является проблемой только в интерпретаторах типа PyPy, где курсор не сразу обрабатывается GC, и в некоторых случаях может привести к тому, что транзакции/блокировки будут открыты дольше, чем это желательно.This change is also backported to: 0.9.9
References: #3285
Устранена утечка, возникавшая в неподдерживаемом и крайне нерекомендуемом случае многократной замены отношения на фиксированном сопоставленном классе с обращением к произвольно растущему числу целевых сопоставлений. При замене старого отношения выдается предупреждение, однако если отображение уже использовалось для запросов, то в некоторых реестрах старое отношение все еще будет упоминаться.
This change is also backported to: 0.9.9
References: #3251
Исправлена ошибка, связанная с мутацией выражений, которая могла проявляться в виде ошибки «Could not locate column» при использовании
Query
для выбора из нескольких анонимных колонок при запросе к SQLite, что являлось побочным эффектом функции «join rewriting», используемой диалектом SQLite.This change is also backported to: 0.9.9
References: #3241
Исправлена ошибка, при которой в предложении ON для
Query.join()
иQuery.outerjoin()
к подклассу с одним наследованием, использующемуof_type()
, не выводился «критерий одной таблицы» в предложении ON, если был установлен флагfrom_joinpoint=True
.This change is also backported to: 0.9.9
References: #3232
Исправлена ошибка, которая затрагивала в целом те же классы событий, что и #3199, когда использовался параметр
named=True
. Некоторые события не регистрировались, а другие некорректно вызывали аргументы события, как правило, в том случае, если событие было «обернуто» для адаптации каким-либо другим способом. Механика «именования» была изменена таким образом, чтобы не мешать сигнатуре аргументов, ожидаемой внутренними функциями-обертками.This change is also backported to: 0.9.8
References: #3197
Исправлена ошибка, затрагивающая многие классы событий, в частности, события ORM, а также события движка, когда обычная логика «де-дублирования» избыточного вызова
listen()
с теми же аргументами не срабатывала для тех событий, где функция слушателя обернута. Утверждение должно было быть сбито в файле registry.py. Теперь это утверждение интегрировано в проверку дедупликации, что позволяет упростить проверку дедупликации в целом.This change is also backported to: 0.9.8
References: #3199
Исправлено предупреждение, которое выдавалось, если сложный самореферентный primaryjoin содержал функции, и при этом была указана remote_side; предупреждение предлагало установить «remote side». Теперь оно выдается только в том случае, если remote_side отсутствует.
This change is also backported to: 0.9.8
References: #3194
Исправлена регрессия, вызванная выпуском #2976 в версии 0.9.4, когда распространение «внешнего соединения» по цепочке объединенных eager-нагрузок некорректно преобразовывало «внутреннее соединение» по пути соединения сиблингов во внешнее соединение, когда распространение «внешнего соединения» должны получать только пути-потомки; кроме того, исправлена проблема, когда распространение «вложенного» соединения происходило некорректно между двумя путями соединения сиблингов.
This change is also backported to: 0.9.7
References: #3131
Исправлена регрессия из 0.9.0, связанная с #2736, когда метод
Query.select_from()
больше не устанавливал корректно сущность «from» объектаQuery
, из-за чего последующие вызовыQuery.filter_by()
илиQuery.join()
не проверяли соответствующую сущность «from» при поиске атрибутов по имени строки.This change is also backported to: 0.9.7
Исправлена ошибка, при которой элементы, сохраненные, удаленные или с изменением первичного ключа в блоке точек сохранения, не участвовали в восстановлении своего прежнего состояния (не в сессии, в сессии, предыдущий PK) после отката внешней транзакции.
This change is also backported to: 0.9.7
References: #3108
Исправлена ошибка при загрузке подзапроса eager в сочетании с
with_polymorphic()
, таргетинг сущностей и колонок в загрузке подзапроса сделан более точным по отношению к этому типу сущностей и другим.This change is also backported to: 0.9.7
References: #3106
Добавлены дополнительные проверки для случая, когда наследующий отображатель неявно объединяет один из своих атрибутов, основанных на столбцах, с атрибутами родителя, причем эти столбцы обычно не обязательно имеют одинаковое значение. Это расширение существующей проверки, которая была добавлена через #1892; однако новая проверка выдает только предупреждение, а не исключение, чтобы позволить приложениям, которые могут полагаться на существующее поведение.
This change is also backported to: 0.9.5
References: #3042
Изменено поведение
load_only()
таким образом, что столбцы первичных ключей всегда добавляются в список столбцов, которые должны быть «не отложены»; в противном случае ORM не сможет загрузить идентификатор строки. По-видимому, можно отложить сопоставленные первичные ключи, и ORM не будет работать, это не изменилось. Но поскольку load_only, по сути, говорит «отложить все, кроме X», более критично, чтобы PK cols не были частью этой отсрочки.This change is also backported to: 0.9.5
References: #3080
Исправлено несколько краевых случаев, возникающих при так называемом сценарии «переключения строки», когда INSERT/DELETE может быть превращен в UPDATE. В такой ситуации отношение «многие-к-одному», установленное в None, или, в некоторых случаях, скалярный атрибут, установленный в None, могут не распознаваться как чистое изменение значения, и, следовательно, UPDATE не сбросит значение, которое было в предыдущей строке. Это связано с некоторыми пока не решенными побочными эффектами работы истории атрибутов, которые заключаются в том, что неявно предполагается, что None не является «изменением» для ранее не установленного атрибута. См. также #3061.
Примечание
Это изменение было ПРЕДУПРЕЖДЕНО в версии 0.9.6. Полное исправление будет в версии 1.0 SQLAlchemy.
This change is also backported to: 0.9.5
References: #3060
В связи с #3060 в единицу работы внесена корректировка, в результате которой загрузка связанных объектов типа «многие-к-одному» в случае графа удаляемых самореферентных объектов производится несколько агрессивнее; загрузка связанных объектов призвана помочь определить правильный порядок удаления, если не задано значение passive_deletes.
This change is also backported to: 0.9.5
Исправлена ошибка в переписывании соединений SQLite, когда анонимизированные имена столбцов из-за повторений некорректно переписывались в подзапросах. Это влияло на запросы SELECT с любым типом подзапроса + join.
This change is also backported to: 0.9.5
References: #3057
Исправления в новой улучшенной булевой коэрцитивности в #2804, где новые правила для «where» и «having» не вступали в силу для аргументов «whereclause» и «having» kw конструкции
select()
, которая также используется вQuery
, поэтому не работала и в ORM.This change is also backported to: 0.9.5
References: #3013
Исправлена ошибка, при которой ошибка прикрепления сессии «объект уже прикреплен к сессии X» не позволяла предотвратить прикрепление объекта к новой сессии, в случае если выполнение продолжалось после появления сообщения об ошибке.
References: #3301
Теперь при обращении к
Query.count()
,Query.update()
,Query.delete()
, а также при запросах к отображенным столбцам, объектамcolumn_property
, функциям и выражениям SQL, полученным на основе отображенных столбцов, в методSession.get_bind()
передается первичноеMapper
изQuery
. Это позволяет сессиям, опирающимся либо на настраиваемые схемыSession.get_bind()
, либо на «привязанные» метаданные, работать во всех соответствующих случаях.Модификатор
PropComparator.of_type()
в сочетании с такими директивами загрузчика, какjoinedload()
иcontains_eager()
, был усовершенствован таким образом, что если встречаются два модификатораPropComparator.of_type()
одинакового базового типа/пути, то они будут объединены в одну «полиморфную» сущность, а не заменят сущность типа A на сущность типа B. Например, объединенная загрузкаA.b.of_type(BSub1)->BSub1.c
в сочетании с объединенной загрузкойA.b.of_type(BSub2)->BSub2.c
создаст единую объединенную загрузкуA.b.of_type((BSub1, BSub2)) -> BSub1.c, BSub2.c
, при этом в запросе не нужно явно указыватьwith_polymorphic
.См.также
Повышенная загрузка полиморфных подтипов - содержит обновленный пример, иллюстрирующий новый формат.
References: #3256
Исправлена поддержка вызова
copy.deepcopy()
при использовании аргументаCascadeOptions
, возникающего в случае использованияcopy.deepcopy()
сrelationship()
(официально не поддерживаемый случай). Pull request courtesy duesenfranz.Исправлена ошибка, при которой операция
Session.expunge()
не полностью отсоединяла данный объект, если он был подвергнут операции удаления, которая была смыта, но не зафиксирована. Это также влияло на смежные операции, такие какmake_transient()
.References: #3139
Предупреждение выдается в случае, если несколько отношений, которые в конечном итоге заполняют столбец внешнего ключа, конфликтуют с другими, когда отношения пытаются скопировать значения из разных исходных столбцов. Это происходит в том случае, когда составные внешние ключи с перекрывающимися столбцами отображаются на отношения, каждое из которых ссылается на свой столбец. Новый раздел документации иллюстрирует этот пример, а также показывает, как решить эту проблему, задавая «чужие» столбцы специально для каждого отношения.
См.также
References: #3230
Метод
Query.update()
теперь преобразует строковые имена ключей в заданном словаре значений в имена отображаемых атрибутов обновляемого класса. Ранее строковые имена принимались напрямую и передавались в оператор обновления ядра без каких-либо средств разрешения относительно отображаемой сущности. Также поддерживаются синонимы и гибридные атрибуты в качестве предметных атрибутовQuery.update()
.References: #3228
Усовершенствован механизм, используемый
Session
для поиска «привязок» (например, движков для использования), такие движки могут быть связаны с классами-миксинами, конкретными подклассами, а также с более широким спектром табличных метаданных, таких как объединенные таблицы наследования.References: #3035
Исправлена ошибка в наследовании одной таблицы, когда цепочка соединений, включающая одну и ту же сущность inh более одного раза (обычно это должно вызывать ошибку), в некоторых случаях, в зависимости от того, от чего происходило соединение, могла неявно псевдонимировать второй случай сущности inh, в результате чего запрос «работал». Но поскольку в случае наследования одной таблицы такое неявное псевдонимов не предполагается, оно действительно «не работало» в полной мере и вводило в заблуждение, поскольку не всегда появлялось.
References: #3233
Предложение ON, выводимое при использовании функций
Query.join()
,Query.outerjoin()
или самостоятельныхjoin()
/outerjoin()
к подклассу с одним наследованием, теперь будет включать «критерий одной таблицы» в предложение ON, даже если в остальном предложение ON развернуто вручную; теперь он добавляется к критериям с помощью AND, так же, как при присоединении к цели с одной таблицей с помощью отношения или аналогичного метода.Это нечто среднее между особенностью и ошибкой.
References: #3222
Значительно изменено поведение меток выражений, в частности, при использовании конструкций ColumnProperty с пользовательскими SQL-выражениями и в сочетании с логикой «порядка по меткам», впервые представленной в 0.9. Исправления включают в себя то, что теперь метка
order_by(Entity.some_col_prop)
будет использовать правила «порядка по меткам», даже если Entity подвергся псевдонимии, либо через рендеринг наследования, либо через использование конструкцииaliased()
; рендеринг одного и того же свойства колонки несколько раз с псевдонимизацией (например,query(Entity.some_prop, entity_alias.some_prop)
) будет помечать каждое вхождение сущности отдельной меткой, и дополнительно правила «порядка по меткам» будут работать для обоих случаев (например,order_by(Entity.some_prop, entity_alias.some_prop)
). Исправлены дополнительные проблемы, которые могли помешать работе логики «порядок по метке» в 0.9, в частности, состояние метки могло измениться таким образом, что «порядок по метке» переставал работать в зависимости от того, как она вызывалась.Изменен подход к применению «единого критерия наследования» при использовании
Query.from_self()
или его обычного пользователяQuery.count()
. Теперь критерий ограничения строк строками с определенным типом указывается во внутреннем подзапросе, а не во внешнем, так что даже если столбец «тип» отсутствует в предложении columns, мы можем фильтровать по нему во «внутреннем» запросе.References: #3177
Внесена небольшая поправка в механику ленивой загрузки, чтобы уменьшить вероятность вмешательства в joinload() в очень редких случаях, когда объект указывает на себя; в этом случае объект ссылается на себя при загрузке своих атрибутов, что может привести к путанице между загрузчиками. Случай использования «объект указывает на себя» не полностью поддерживается, но исправление также устраняет некоторые накладные расходы, поэтому пока что является частью тестирования.
References: #3145
ORM-событие «resurrect» было удалено. Этот крючок не имел смысла с тех пор, как в 0.8 была удалена старая система «изменяемых атрибутов».
References: #3171
Исправлена ошибка, при которой события «set» атрибутов или столбцов с
@validates
вызывали события в процессе flush, когда эти столбцы были объектами операции «fetch and populate», например, автоинкрементный первичный ключ, значение по умолчанию на стороне Python или значение по умолчанию на стороне сервера, «с нетерпением» полученное через RETURNING.References: #3167
Представление
IdentityMap
, открытое изSession.identity_map
, теперь возвращает списки дляitems()
иvalues()
в Py3K. В ранних версиях портирования на Py3K они возвращали итераторы, тогда как технически они должны были быть «итерируемыми представлениями».»Оценщик» для query.update()/delete() не работает с многотабличными обновлениями и должен быть установлен в значение synchronize_session=False или synchronize_session=“fetch; теперь это вызывает исключение с сообщением об изменении настройки синхронизации. Это обновлено по сравнению с предупреждением, выдаваемым в версии 0.9.7.
References: #3117
Внесена поправка в механику атрибутов, касающаяся случая, когда значение неявно инициализируется в None при первом доступе; это действие, которое всегда приводило к заселению атрибута, больше не приводит к этому; значение None возвращается, но базовый атрибут не получает события set. Это соответствует принципу работы коллекций и позволяет механике атрибутов вести себя более последовательно; в частности, получение атрибута, не имеющего значения, не приводит к сбрасыванию события, которое должно произойти, если значение действительно установлено в None.
где связанные параметры отображаются в виде строк на основе опции времени компиляции. Работа над этой функцией предоставлена Добесом Вандермеером.
References: #3061
orm declarative¶
Конструкция
declared_attr
в сочетании с декларативной имеет улучшенное поведение и возможности. Теперь декорированная функция при вызове будет иметь доступ к конечным экземплярам столбцов, присутствующим в локальном миксине, а также будет вызываться ровно один раз для каждого сопоставленного класса, при этом возвращаемый результат будет мемоизирован. Также добавлен новый модификаторdeclared_attr.cascading
.References: #3150
Исправлена ошибка «„NoneType“ object has no attribute „concrete“» при использовании
AbstractConcreteBase
совместно с подклассом, в котором объявлен__abstract__
.This change is also backported to: 0.9.8
References: #3185
Исправлена ошибка, при которой использование миксина
__abstract__
в середине декларативной иерархии наследования не позволяло корректно распространять атрибуты и конфигурацию из базового класса в наследующий класс.Отношение, установленное с помощью
declared_attr
на базовом классеAbstractConcreteBase
, теперь будет автоматически настроено на отображение абстрактной базы, помимо того, что оно будет настроено на последующие конкретные классы, как обычно.References: #2670
examples¶
Добавлен новый пример, иллюстрирующий материализованные пути с использованием последних возможностей отношений. Пример предоставлен Джеком Чжоу.
This change is also backported to: 0.9.5
Новый набор примеров, предназначенный для детального изучения производительности SQLAlchemy ORM и Core, а также DBAPI с различных точек зрения. Набор запускается в контейнере, который обеспечивает встроенные средства профилирования как в виде консольного вывода, так и в графическом виде с помощью инструмента RunSnake.
См.также
Пример Версионирование с помощью таблицы истории обновлен таким образом, что отображаемые столбцы повторно отображаются в соответствии с именами столбцов, а также группировкой столбцов; в частности, это позволяет столбцам, явно сгруппированным в сценарии объединенного наследования с одинаковыми именами столбцов, быть отображенными таким же образом в отображениях истории, избегая предупреждений, добавленных в серии 0.9 относительно этого шаблона, и обеспечивая одинаковое представление ключей атрибутов.
This change is also backported to: 0.9.9
Исправлена ошибка в примере examples/generic_associations/discriminator_on_association.py, когда подклассы AddressAssociation не отображались как «однотабличное наследование», что приводило к проблемам при дальнейшей попытке использования отображений.
This change is also backported to: 0.9.9
engine¶
Добавлены новые аксессоры пользовательского пространства для просмотра уровней изоляции транзакций;
Connection.get_isolation_level()
,Connection.default_isolation_level
.This change is also backported to: 0.9.9
Добавлено новое событие
ConnectionEvents.handle_error()
, являющееся более полноценной и всеобъемлющей заменойConnectionEvents.dbapi_error()
.This change is also backported to: 0.9.7
References: #3076
Новый стиль предупреждения может быть выдан, который будет «фильтровать» до N вхождений параметризованной строки. Это позволяет передавать параметризованные предупреждения, которые могут ссылаться на свои аргументы, фиксированное количество раз, пока фильтры предупреждений Python не смогут их отсеять, и предотвращает неограниченный рост памяти в реестрах предупреждений Python.
References: #3178
Исправлена ошибка в
Connection
и пуле, когда методConnection.invalidate()
или аннулирование из-за разъединения базы данных при использовании параметраisolation_level
с параметромConnection.execution_options()
приводили к ошибке; при этом «финализатор», сбрасывающий уровень изоляции, вызывался на уже не открытом соединении.This change is also backported to: 0.9.9
References: #3302
Предупреждение выдается, если параметр
isolation_level
используется сConnection.execution_options()
при наличииTransaction
; DBAPI и/или диалекты SQLAlchemy, такие как psycopg2, MySQLdb, могут неявно откатить или зафиксировать транзакцию, или не изменять настройку до следующей транзакции, так что это никогда не будет безопасно.This change is also backported to: 0.9.9
References: #3296
Опции выполнения, передаваемые в
Engine
черезcreate_engine.execution_options
илиEngine.update_execution_options()
, не передаются в специальныйConnection
, используемый для инициализации диалекта в событии «первое подключение»; обычно диалекты выполняют собственные запросы на этом этапе, и ни одна из имеющихся опций не должна применяться здесь. В частности, опция «autocommit» приводила к тому, что попытка автокоммита в этом начальном соединении завершалась с ошибкой AttributeError из-за нестандартного состоянияConnection
.This change is also backported to: 0.9.8
References: #3200
Строковые ключи, используемые для определения столбцов, на которые оказывается воздействие при INSERT или UPDATE, теперь сортируются, когда они вносят вклад в ключ кэша «скомпилированный кэш». Ранее эти ключи не были детерминированно упорядочены, что означало, что один и тот же оператор мог быть кэширован несколько раз по эквивалентным ключам, что приводило к затратам как памяти, так и производительности.
This change is also backported to: 0.9.8
References: #3165
Исправлена ошибка, которая возникала, если при первом подключении движка и выполнении начальных проверок возникало исключение DBAPI, и это исключение не являлось исключением разъединения, однако при попытке закрыть курсор возникала ошибка. В этом случае реальное исключение будет заблокировано, так как мы пытались зарегистрировать исключение закрытия курсора через пул соединений и потерпели неудачу, поскольку пытались получить доступ к регистратору пула способом, не подходящим для данного конкретного сценария.
This change is also backported to: 0.9.5
References: #3063
Исправлено несколько ситуаций «двойного аннулирования», когда аннулирование соединения происходило внутри уже критической секции типа connection.close(); в конечном счете, эти ситуации вызваны изменением в #2907, когда функция «сброс при возврате» обращается к соединению/транзакции для обработки, где может быть поймано «обнаружение разъединения». Однако возможно, что более позднее изменение в #2985 сделало это более вероятным, поскольку операция «аннулирование соединения» выполняется гораздо быстрее, так как проблема более воспроизводима на 0.9.4, чем на 0.9.3.
Теперь в любой секции, где может произойти аннулирование, добавлены проверки, останавливающие дальнейшие запрещенные операции над аннулированным соединением. Это включает два исправления - на уровне движка и на уровне пула. Хотя проблема наблюдалась в случаях с высококонкурентными событиями gevent, теоретически она может возникнуть в любом сценарии, где разрыв соединения происходит в рамках операции закрытия соединения.
This change is also backported to: 0.9.5
References: #3043
Процедуры обработки ошибок и обертывания на уровне движка теперь будут действовать во всех случаях использования соединений на движке, в том числе при использовании пользовательских процедур подключения через параметр
create_engine.creator
, а также при ошибке подключенияConnection
при повторной проверке.References: #3266
Удаление (или добавление) слушателя события во время выполнения самого события из слушателя или из параллельного потока теперь вызывает ошибку RuntimeError, поскольку используемая коллекция теперь является экземпляром
collections.deque()
и не поддерживает изменения во время итерации. Ранее использовался обычный список Python, удаление которого изнутри самого события приводило к тихим сбоям.References: #3163
sql¶
Немного смягчен контракт для
Index
, теперь в качестве цели можно указывать выражениеtext()
; индекс больше не должен иметь столбца, связанного с таблицей, если индекс добавляется в таблицу вручную, либо через объявление inline, либо черезTable.append_constraint()
.This change is also backported to: 0.9.5
References: #3028
Добавлен новый флаг
between.symmetric
, при установке которого в True происходит рендеринг «BETWEEN SYMMETRIC». Также добавлен новый оператор отрицания «notbetween_op», который теперь позволяет выражению типа~col.between(x, y)
отображаться как «col NOT BETWEEN x AND y», а не как строка NOT, заключенная в круглые скобки.This change is also backported to: 0.9.5
References: #2990
Компилятор SQL теперь генерирует отображение ожидаемых столбцов таким образом, что они сопоставляются с полученным набором результатов позиционно, а не по имени. Изначально это рассматривалось как способ обработки случаев, когда возвращались столбцы с труднопредсказуемыми именами, хотя в современном использовании эта проблема преодолевается за счет анонимной маркировки. В данной версии подход позволяет сократить количество вызовов функций на один результат на несколько десятков вызовов или больше для больших наборов столбцов результатов. Подход по-прежнему деградирует в современную версию старого подхода, если существует расхождение в размерах между скомпилированным набором столбцов и полученным, так что для сценариев частично или полностью текстовой компиляции, где эти списки могут не совпадать, проблемы не существует.
References: #918
Буквальные значения внутри
DefaultClause
, вызываемого при использовании параметраColumn.server_default
, теперь будут выводиться с использованием «inline» компилятора, так что они будут выводиться как есть, а не как связанные параметры.References: #3087
Тип выражения сообщается, когда объект, переданный в блок SQL-выражения, не может быть интерпретирован как SQL-фрагмент; pull request courtesy Ryan P. Kelly.
В метод
Table.tometadata()
добавлен новый параметрTable.tometadata.name
. АналогичноTable.tometadata.schema
, этот аргумент заставляет копируемый объектTable
принимать новое имя вместо существующего. Интересной возможностью, которую это добавляет, является копирование объектаTable
в эту же цельMetaData
с новым именем. Pull request courtesy n.d. parker.Сообщения об исключениях были несколько усовершенствованы. SQL-оператор и параметры не отображаются, если их нет, что уменьшает путаницу в сообщениях об ошибках, не связанных с оператором. Отображается полное имя модуля и класса исключения на уровне DBAPI, что дает понять, что это обернутое исключение DBAPI. Само утверждение и параметры заключены в скобки, чтобы лучше изолировать их от сообщения об ошибке и друг от друга.
References: #3172
Insert.from_select()
теперь включает значения по умолчанию для Python и SQL-выражений, если иное не указано; ограничение, при котором значения по умолчанию для несерверных колонок не включались в INSERT FROM SELECT, теперь снято, и эти выражения выводятся как константы в оператор SELECT.Конструкция
UniqueConstraint
теперь включается при отражении объектаTable
для баз данных, где это применимо. Для того чтобы добиться этого с достаточной точностью, в MySQL и PostgreSQL появились функции, корректирующие дублирование индексов и уникальных ограничений при отражении таблиц, индексов и ограничений. В случае MySQL понятие «уникальное ограничение» не зависит от понятия «уникальный индекс», поэтому для этого бэкендаUniqueConstraint
продолжает оставаться непредставимым для отраженногоTable
. Для PostgreSQL запрос, используемый для обнаружения индексов наpg_index
, был усовершенствован для проверки наличия аналогичной конструкции вpg_constraint
, и неявно построенный уникальный индекс не включается в отраженныйTable
.В обоих случаях методы
Inspector.get_indexes()
иInspector.get_unique_constraints()
возвращают обе конструкции по отдельности, но включают новый маркерduplicates_constraint
в случае PostgreSQL илиduplicates_index
в случае MySQL для указания на обнаружение этого условия. Pull request любезно предоставлен Йоханнесом Эрдфельтом.References: #3184
Добавлен новый метод
Select.with_statement_hint()
и ORM-методQuery.with_statement_hint()
для поддержки подсказок на уровне утверждений, не относящихся к таблице.References: #3206
Параметр
info
добавлен в качестве аргумента конструктора ко всем конструкциям схемы, включаяMetaData
,Index
,ForeignKey
,ForeignKeyConstraint
,UniqueConstraint
,PrimaryKeyConstraint
,CheckConstraint
.References: #2963
Флаг
Table.autoload_with
теперь подразумевает, чтоTable.autoload
должен бытьTrue
. Pull request любезно предоставлен Маликом Диарра.References: #3027
Методы
Select.limit()
иSelect.offset()
теперь принимают в качестве аргументов не только целочисленные значения, но и любые SQL-выражения. Обычно это используется для передачи связанного параметра, который впоследствии может быть заменен значением, что позволяет кэшировать SQL-запрос на стороне Python. Данная реализация полностью обратно совместима с существующими диалектами сторонних разработчиков, однако те диалекты, которые реализуют специальные системы LIMIT/OFFSET, потребуют модификации для использования новых возможностей. Limit и offset также поддерживают режим «literal_binds»,References: #3034
Конструкции
column()
иtable()
теперь импортируются из пространства имен «from sqlalchemy», как и все остальные конструкции Core.Неявное преобразование строк в конструкции
text()
при передаче их большинству методов-строителейselect()
, а такжеQuery
теперь выдает предупреждение о том, что передается только обычная строка. При этом преобразование текста по-прежнему выполняется нормально. Единственный метод, принимающий строку без предупреждения, - это методы «ссылки на метку», такие как order_by(), group_by(); теперь эти функции во время компиляции будут пытаться разрешить единственный строковый аргумент в выражение столбца или метки, присутствующее в selectable; если такового не находится, выражение все равно отображается, но вы снова получаете предупреждение. Это объясняется тем, что неявное преобразование строки в текст в наши дни чаще всего оказывается неожиданным, и лучше, чтобы пользователь при передаче необработанной строки указывал Core/ORM, в каком направлении следует действовать. Учебные пособия по Core/ORM были обновлены и теперь более подробно рассматривают работу с текстом.References: #2992
Исправлена ошибка в
Enum
и других подклассахSchemaType
, когда прямое связывание типа сMetaData
приводило к зависанию, когда наMetaData
выдавались события (например, события create).This change is also backported to: 0.9.7, 0.8.7
References: #3124
Исправлена ошибка в системе пользовательских операторов плюс
TypeEngine.with_variant()
, при которой использованиеTypeDecorator
в сочетании с variant приводило к ошибке MRO при использовании оператора сравнения.This change is also backported to: 0.9.7, 0.8.7
References: #3102
Исправлена ошибка в конструкции INSERT..FROM SELECT, когда при выборе из UNION объединение заворачивалось в анонимный (например, немаркированный) подзапрос.
This change is also backported to: 0.9.5, 0.8.7
References: #3044
Исправлена ошибка, при которой
Table.update()
иTable.delete()
выдавали пустое предложение WHERE, когда применялись пустыеand_()
илиor_()
или другие пустые выражения. Теперь это соответствует таковому дляselect()
.This change is also backported to: 0.9.5, 0.8.7
References: #3045
Добавлен флаг
native_enum
к выводу__repr__()
изEnum
, что особенно важно при использовании его с автогенерацией Alembic. Pull request любезно предоставлен Dimitris Theodorou.This change is also backported to: 0.9.9
Исправлена ошибка, при которой использование
TypeDecorator
, реализующего тип, который также являетсяTypeDecorator
, приводило к ошибке Python «Cannot create a consistent method resolution order (MRO)», когда к объекту, использующему этот тип, применялось любое выражение сравнения SQL.This change is also backported to: 0.9.9
References: #3278
Исправлена проблема, при которой столбцы из SELECT, встроенного в INSERT, либо через предложение values, либо как «from select», загрязняли типы столбцов, используемые в наборе результатов, формируемом предложением RETURNING, когда столбцы из обоих операторов имели одинаковые имена, что приводило к потенциальным ошибкам или неправильной адаптации при извлечении возвращаемых строк.
This change is also backported to: 0.9.9
References: #3248
Исправлена ошибка, из-за которой большое количество SQL-элементов в пакете sql не могли успешно выполнить
__repr__()
из-за отсутствия атрибутаdescription
, что приводило к переполнению рекурсии, когда внутренняя ошибка AttributeError вызывала__repr__()
.This change is also backported to: 0.9.8
References: #3195
Настроено отражение таблицы/индекса таким образом, что если индекс сообщает о столбце, который не обнаружен в таблице, то выдается предупреждение и столбец пропускается. Это может происходить в некоторых особых ситуациях с системными столбцами, как это наблюдалось в Oracle.
This change is also backported to: 0.9.8
References: #3180
Исправлена ошибка в CTE, когда аргумент компилятора
literal_binds
не всегда корректно распространялся, когда один CTE ссылался в операторе на другой псевдослучайный CTE.This change is also backported to: 0.9.8
References: #3154
Исправлена регрессия 0.9.7, вызванная использованием #3067 в сочетании с неправильно названным юнит-тестом, в результате чего так называемые «схемные» типы, такие как
Boolean
иEnum
, больше не могли быть замаринованы.This change is also backported to: 0.9.8
Исправлена ошибка, связанная с использованием соглашения об именовании, когда при использовании соглашения о проверке ограничений, включающего
constraint_name
, все типыBoolean
иEnum
также должны были иметь имена, поскольку они неявно создавали ограничение, даже если конечный бэкенд не требовал генерации ограничения, например, PostgreSQL. Механика именования для этих ограничений была реорганизована таким образом, что определение именования происходит во время компиляции DDL, а не во время конструирования ограничений/таблиц.This change is also backported to: 0.9.7
References: #3067
Исправлена ошибка в общих табличных выражениях, из-за которой позиционные связанные параметры могли быть выражены в неправильном конечном порядке, когда CTE были вложены определенным образом.
This change is also backported to: 0.9.7
References: #3090
Исправлена ошибка, при которой в многозначной конструкции
Insert
для литеральных SQL-выражений не проверялись последующие записи значений, кроме первого заданного.This change is also backported to: 0.9.7
References: #3069
В итерацию dialect_kwargs для Python версии < 2.6.5 добавлен шаг «str()», позволяющий обойти ошибку «no unicode keyword arg», поскольку в некоторых процессах рефлексии эти аргументы передаются как ключевые.
This change is also backported to: 0.9.7
References: #3123
Метод
TypeEngine.with_variant()
теперь будет принимать в качестве аргумента класс типа, который внутренне преобразуется в экземпляр, по той же схеме, что и в других конструкциях, таких какColumn
.This change is also backported to: 0.9.7
References: #3122
Флаг
Column.nullable
неявно устанавливается в значениеFalse
, когда на эту таблицуColumn
ссылаются в явномPrimaryKeyConstraint
для этой таблицы. Теперь это поведение соответствует поведению, когда для самогоColumn
установлен флагColumn.primary_key
в значениеTrue
, что должно быть абсолютно эквивалентным случаем.This change is also backported to: 0.9.5
References: #3023
Исправлена ошибка, при которой методы перегрузки операторов
Operators.__and__()
,Operators.__or__()
иOperators.__invert__()
не могли быть переопределены в пользовательской реализацииComparator
.This change is also backported to: 0.9.5
References: #3012
Исправлена ошибка в новом методе
DialectKWArgs.argument_for()
, когда добавление аргумента для конструкции, не включенной ранее ни для каких специальных аргументов, приводило к ошибке.This change is also backported to: 0.9.5
References: #3024
Исправлена ошибка, появившаяся в 0.9, когда новая функция «ORDER BY <labelname>» из #1068 не применяла правила кавычек к имени метки, отображаемому в ORDER BY.
This change is also backported to: 0.9.5
Восстановлен импорт для
Function
в пространство имен импортаsqlalchemy.sql.expression
, который был удален в начале 0.9.This change is also backported to: 0.9.5
Многозначная версия
Insert.values()
была исправлена для более удобной работы с таблицами, имеющими значения и/или функции по умолчанию на стороне Python, а также значения по умолчанию на стороне сервера. Теперь функция будет работать с диалектом, использующим «позиционные» параметры; Python-вызываемая функция будет вызываться отдельно для каждой строки, как и в случае вызова в стиле «executemany»; столбец по умолчанию на стороне сервера больше не будет неявно принимать значение, явно указанное для первой строки, отказываясь вызываться без явного значения.References: #3288
Исправлена ошибка в методе
Table.tometadata()
, когдаCheckConstraint
, связанный с объектом типаBoolean
илиEnum
, удваивался в целевой таблице. Теперь процесс копирования отслеживает создание этого объекта ограничений как локального для объекта типа.References: #3260
Поведенческий контракт коллекции
ForeignKeyConstraint.columns
был приведен в соответствие; теперь этот атрибут являетсяColumnCollection
, как и все остальные ограничения, и инициализируется в тот момент, когда ограничение связано сTable
.References: #3243
Атрибут
Column.key
теперь используется в качестве источника анонимных имен связанных параметров в выражениях, что соответствует существующему использованию этого значения в качестве ключа при отображении в операторах INSERT или UPDATE. Это позволяет использоватьColumn.key
в качестве «замещающей» строки для решения проблемы сложного имени столбца, которое не может быть преобразовано в имя связанного параметра. Заметим, что стиль параметра в любом случае настраивается наcreate_engine()
, и большинство DBAPI сегодня поддерживают именованный и позиционный стиль.References: #3245
Исправлено имя параметра
PoolEvents.reset.dbapi_connection
, передаваемого этому событию; в частности, это влияет на использование стиля аргумента «named» для этого события. Pull request любезно предоставлен Джейсоном Голдбергером.В результате изменения, внесенного в 0.9, была отменена «синглтонная» природа «констант»
null()
,true()
иfalse()
. Эти функции, возвращающие объект-«синглтон», приводили к тому, что разные экземпляры рассматривались как один и тот же независимо от лексического использования, что, в частности, влияло на отображение предложения columns в операторе SELECT.References: #3170
Исправлена ошибка, при которой «разветвленное» соединение, то есть такое, которое получается при вызове
Connection.connect()
, не передавало статус недействительности родительскому соединению. Архитектура ветвления была немного подправлена, так что разветвленное соединение передает родительскому все статусы и операции, связанные с недействительностью.References: #3215
Исправлена ошибка, при которой «разветвленное» соединение, то есть такое, которое получается при вызове
Connection.connect()
, не передавало статус транзакции родительскому соединению. Архитектура ветвления была немного изменена, так что разветвленное соединение передает родительскому все транзакционные статусы и операции.References: #3190
Использование
Insert.from_select()
теперь подразумеваетinline=True
наinsert()
. Это позволяет исправить ошибку, когда конструкция INSERT…FROM SELECT случайно компилировалась как «неявный возврат» на поддерживающих бэкендах, что приводило к поломке в случае INSERT, вставляющего нулевые строки (поскольку неявный возврат ожидает строку), а также к произвольным возвращаемым данным в случае INSERT, вставляющего несколько строк (например, только первую строку из многих). Аналогичное изменение коснулось и INSERT..VALUES с несколькими наборами параметров: для этого оператора также больше не будет выдаваться неявный RETURNING. Поскольку обе эти конструкции имеют дело с переменным количеством строк, аксессорResultProxy.inserted_primary_key
не применяется. Ранее в документации было указано, что при использовании INSERT…FROM SELECT можно предпочестьinline=True
, так как некоторые базы данных не поддерживают возврат и поэтому не могут выполнять «неявный» возврат, но в любом случае для INSERT…FROM SELECT не требуется неявный возврат. Для возврата переменного числа строк результата, если требуется вставить данные, следует использовать обычные явныеInsert.returning()
.References: #3169
Пользовательские диалекты, реализующие
GenericTypeCompiler
, теперь могут быть построены таким образом, чтобы методы visit получали указание на принадлежащий им объект выражения, если таковой имеется. Любой метод visit, принимающий аргументы в виде ключевых слов (например,**kw
), в большинстве случаев будет получать аргумент в виде ключевого словаtype_expression
, ссылающийся на объект выражения, в котором содержится данный тип. Для столбцов в DDL класс компилятора диалекта может потребовать изменить свой методget_column_specification()
для поддержки и этого. МетодUserDefinedType.get_col_spec()
также будет приниматьtype_expression
, если в сигнатуре аргумента он содержит**kw
.References: #3074
schema¶
Система генерации DDL-файлов
MetaData.create_all()
иMetaData.drop_all()
была усовершенствована таким образом, чтобы в большинстве случаев автоматически справляться с взаимозависимыми ограничениями внешнего ключа; необходимость в использовании флагаForeignKeyConstraint.use_alter
значительно уменьшилась. Система работает и для ограничений, которым заранее не присваивается имя; только в случае DROP требуется имя хотя бы для одного из ограничений, участвующих в цикле.References: #3282
Добавлен новый аксессор
Table.foreign_key_constraints
, дополняющий коллекциюTable.foreign_keys
, а такжеForeignKeyConstraint.referred_table
.Конструкция
CheckConstraint
теперь поддерживает соглашения об именовании, включающие лексему%(column_0_name)s
; выражение ограничения сканируется на наличие столбцов. Кроме того, соглашения об именах для проверочных ограничений, не включающие маркер%(constraint_name)s
, теперь будут работать дляSchemaType
-генерируемых ограничений, таких какBoolean
иEnum
; в 0.9.7 это перестало работать из-за #3067.
postgresql¶
Добавлена поддержка ключевого слова
CONCURRENTLY
с индексами PostgreSQL, устанавливаемыми с помощьюpostgresql_concurrently
. Pull request любезно предоставлен Iuri de Silvio.См.также
This change is also backported to: 0.9.9
Добавлена поддержка «вменяемого подсчета нескольких строк» в драйвере pg8000, что в основном относится к использованию версионности в ORM. Функция определяется по версии используемого драйвера pg8000 1.9.14 или выше. Pull request любезно предоставлен Tony Locke.
This change is also backported to: 0.9.8
В оператор
ColumnOperators.match()
добавлен аргумент kwpostgresql_regconfig
, позволяющий указать аргумент «reg config» в выдаваемой функцииto_tsquery()
. Pull request любезно предоставлен Джонатаном Ванаско.This change is also backported to: 0.9.7
References: #3078
Добавлена поддержка PostgreSQL JSONB через
JSONB
. Pull request любезно предоставлен Дамианом Диммихом.This change is also backported to: 0.9.7
Добавлена поддержка уровня изоляции AUTOCOMMIT при использовании pg8000 DBAPI. Pull request любезно предоставлен Tony Locke.
This change is also backported to: 0.9.5
Добавлен новый флаг
ARRAY.zero_indexes
для типа PostgreSQLARRAY
. При установке флагаTrue
ко всем значениям индексов массивов перед передачей в базу данных будет добавляться значение, равное единице, что позволяет улучшить взаимодействие между нулевыми индексами в стиле Python и единичными индексами в PostgreSQL. Pull request любезно предоставлен Алексеем Терентьевым.This change is also backported to: 0.9.5
References: #2785
Диалект PG8000 теперь поддерживает параметр
create_engine.encoding
, устанавливая кодировку клиента при соединении, которая затем перехватывается pg8000. Pull request любезно предоставлен Тони Локом (Tony Locke).Добавлена поддержка встроенной в PG8000 функции JSONB. Pull request любезно предоставлен Тони Локком.
Добавлена поддержка psycopg2cffi DBAPI на pypy. Pull request courtesy shauns.
References: #3052
Добавлена поддержка ключевого слова FILTER применительно к агрегатным функциям, поддерживаемая PostgreSQL 9.4. Pull request любезно предоставлен Ilja Everilä.
См.также
Добавлена поддержка отражения материализованных представлений и внешних таблиц, а также поддержка материализованных представлений внутри
Inspector.get_view_names()
и новый методPGInspector.get_foreign_table_names()
, доступный на версии PostgreSQLInspector
. Pull request любезно предоставлен Rodrigo Menezes.References: #2891
Добавлена поддержка опций PG-таблиц TABLESPACE, ON COMMIT, WITH(OUT) OIDS и INHERITS при выводе DDL с помощью конструкции
Table
. Pull request courtesy malikdiarra.См.также
References: #2051
Добавлен новый метод
PGInspector.get_enums()
, при использовании которого инспектор для PostgreSQL будет выдавать список типов ENUM. Pull request любезно предоставлен Ильей Пекельным.Добавлен флаг
hashable=False
для типа PGHSTORE
, необходимый для того, чтобы ORM могла пропустить попытку «хэширования» колонки HSTORE, отображенной на ORM, при запросе ее в смешанном списке колонок/сущностей. Исправление любезно предоставлено Gunnlaugur Þór Briem.This change is also backported to: 0.9.5, 0.8.7
References: #3053
Добавлено новое сообщение «disconnect» - «соединение было закрыто неожиданно». По-видимому, это связано с новыми версиями SSL. Pull request любезно предоставлен Antti Haapala.
This change is also backported to: 0.9.5, 0.8.7
Исправлена поддержка типов UUID в PostgreSQL в сочетании с типом ARRAY при использовании psycopg2. Диалект psycopg2 теперь использует хук psycopg2.extras.register_uuid(), благодаря чему значения UUID всегда передаются в/из DBAPI как объекты UUID(). Флаг
UUID.as_uuid
по-прежнему соблюдается, только в psycopg2 при его отключении необходимо преобразовывать возвращаемые UUID-объекты обратно в строки.This change is also backported to: 0.9.9
References: #2940
Добавлена поддержка типа данных
postgresql.JSONB
при использовании psycopg2 2.5.4 и выше, в котором реализована нативная конвертация данных JSONB, поэтому конвертеры SQLAlchemy должны быть отключены; дополнительно добавлено расширение psycopg2extras.register_default_jsonb
, которое используется для установки десериализатора JSON, передаваемого диалекту через аргументjson_deserializer
. Также исправлены тесты интеграции с PostgreSQL, которые на самом деле обходили тип JSONB, а не JSON. Pull request любезно предоставлен Матеушем Сусиком.This change is also backported to: 0.9.9
Исправлено использование флага «array_oid» при регистрации типа HSTORE на старых версиях psycopg2 < 2.4.3, не поддерживающих этот флаг, а также использование хука нативного json-сериализатора «register_default_json» с пользовательским значением
json_deserializer
на psycopg2 версии < 2.5, не включающей нативный json.This change is also backported to: 0.9.9
Исправлена ошибка, при которой диалект PostgreSQL не мог вывести выражение в
Index
, не соответствующее непосредственно столбцу, привязанному к таблице; обычно это происходило, когда конструкцияtext()
являлась одним из выражений в индексе; или мог неправильно интерпретировать список выражений, если одно или несколько из них являлись таким выражением.This change is also backported to: 0.9.9
References: #3174
Возвращаясь к этой проблеме, впервые исправленной в 0.9.5, следует отметить, что, по-видимому, аксессор psycopg2
.closed
не так надежен, как мы предполагали, поэтому мы добавили явную проверку на наличие сообщений исключений «SSL SYSCALL error: Bad file descriptor» и «SSL SYSCALL error: EOF detected» при обнаружении сценария is-disconnect. В качестве первой проверки мы продолжим обращаться к файлу connection.closed в psycopg2.This change is also backported to: 0.9.8
References: #3021
Исправлена ошибка, при которой тип PostgreSQL JSON не мог сохранить или иным образом отобразить значение столбца SQL NULL, а не JSON-кодировку
'null'
. Для поддержки этого случая изменения заключаются в следующем:Теперь можно указать значение
null()
, которое всегда будет приводить к NULL-значению в результате выполнения оператора.Добавлен новый параметр
JSON.none_as_null
, который при значении True указывает, что значение PythonNone
должно сохраняться как SQL NULL, а не как JSON-кодировка'null'
.
Получение NULL как None также исправлено для DBAPI, отличных от psycopg2, а именно pg8000.
This change is also backported to: 0.9.8
References: #3159
Система обертывания исключений для ошибок DBAPI теперь может работать с нестандартными исключениями DBAPI, такими как psycopg2 TransactionRollbackError. Теперь эти исключения будут вызываться с использованием ближайшего доступного подкласса в
sqlalchemy.exc
, в случае TransactionRollbackError -sqlalchemy.exc.OperationalError
.This change is also backported to: 0.9.8
References: #3075
Исправлена ошибка в объекте
array
, когда при сравнении с обычным списком Python не использовался правильный конструктор массива. Pull request любезно предоставлен Andrew.This change is also backported to: 0.9.8
References: #3141
Добавлен поддерживаемый метод
FunctionElement.alias()
в функции, например, в конструкциюfunc
. Ранее поведение этого метода было неопределенным. Текущее поведение имитирует поведение до версии 0.9.4. Функция превращается в одноколоночное предложение FROM с заданным именем псевдонима, где сам столбец является анонимным.This change is also backported to: 0.9.8
References: #3137
Исправлена ошибка, появившаяся в 0.9.5 благодаря новой функции уровня изоляции pg8000, когда параметр уровня изоляции на уровне движка приводил к ошибке при подключении.
This change is also backported to: 0.9.7
References: #3134
Аксессор psycopg2
.closed
теперь используется при определении того, является ли исключение ошибкой «разъединения»; в идеале это должно устранить необходимость в какой-либо другой проверке сообщения исключения для определения разъединения, однако мы оставим существующие сообщения в качестве запасного варианта. Это должно позволить обрабатывать более новые случаи, например, условия «SSL EOF». Pull request любезно предоставлен Дирком Мюллером.This change is also backported to: 0.9.5
References: #3021
Тип PostgreSQL
ENUM
будет выдавать инструкцию DROP TYPE при вызове обычногоtable.drop()
, если объект не связан напрямую с объектомMetaData
. Для того чтобы учесть случай использования перечислимого типа, разделяемого между несколькими таблицами, тип должен быть связан непосредственно с объектомMetaData
; в этом случае тип будет создан только на уровне метаданных или при непосредственном создании. Правила создания/удаления перечислимых типов PostgreSQL в целом были сильно переработаны.References: #3319
Метод
PGDialect.has_table()
теперь будет запрашиватьpg_catalog.pg_table_is_visible(c.oid)
, а не проверять точное совпадение схемы, когда имя схемы равно None; это сделано для того, чтобы метод также проиллюстрировал наличие временных таблиц. Обратите внимание, что это изменение поведения, поскольку PostgreSQL позволяет не временной таблице молча перезаписывать существующую временную таблицу с тем же именем, поэтому это изменяет поведениеcheckfirst
в этом необычном сценарии.References: #3264
В диалект PostgreSQL добавлен новый тип
OID
. Хотя в PG тип «oid» обычно является частным типом, который не раскрывается в современных версиях, существуют некоторые случаи использования PG, такие как поддержка больших объектов, где эти типы могут быть раскрыты, а также в некоторых случаях использования отражения схемы, сообщаемой пользователем.This change is also backported to: 0.9.5
References: #3002
mysql¶
Диалект MySQL теперь выдает TIMESTAMP с NULL / NOT NULL во всех случаях, так что MySQL 5.6.6 с включенным флагом
explicit_defaults_for_timestamp
позволит TIMESTAMP продолжать работать как ожидалось, когдаnullable=False
. Существующие приложения не затронуты, поскольку SQLAlchemy всегда выдавала NULL для столбца TIMESTAMP, имеющего значениеnullable=True
.References: #3155
Обновлен флаг «supports_unicode_statements» на True для MySQLdb и Pymysql под Python 2. Это относится к самим SQL-операторам, а не к параметрам, и затрагивает такие вопросы, как имена таблиц и столбцов, использующие не ASCII-символы. В современных версиях эти драйверы поддерживают объекты Python 2 Unicode без проблем.
References: #3121
Диалект
gaerdbms
больше не нужен и выдает предупреждение об устаревании. Теперь Google рекомендует использовать диалект MySQLdb напрямую.This change is also backported to: 0.9.9
References: #3275
Ошибка MySQL 2014 «Commands out of sync» в современных версиях MySQL-Python выдается как ProgrammingError, а не OperationalError; все коды ошибок MySQL, проверяемые на «is disconnect», теперь проверяются в рамках OperationalError и ProgrammingError независимо друг от друга.
This change is also backported to: 0.9.7, 0.8.7
References: #3101
Исправлена ошибка, при которой имена столбцов, добавляемые в параметр
mysql_length
в индексе, для распознавания должны были иметь одинаковые кавычки для имен, взятых в кавычки. Исправление делает кавычки необязательными, но при этом сохраняет прежнее поведение для обратной совместимости с теми, кто использует обходной путь.This change is also backported to: 0.9.5, 0.8.7
References: #3085
Добавлена поддержка отражения таблиц, индекс которых включает KEY_BLOCK_SIZE, с помощью знака равенства. Pull request любезно предоставлен Шоном Макгиверном (Sean McGivern).
This change is also backported to: 0.9.5, 0.8.7
Добавлена проверка версии диалекта MySQLdb, окружающая проверку колляции „utf8_bin“, так как на сервере MySQL < 5.0 она не работает.
This change is also backported to: 0.9.9
References: #3274
Mysqlconnector начиная с версии 2.0, вероятно, как побочный эффект слияния с python 3, теперь не ожидает, что знаки процента (например, используемые в операторе modulus и других) будут удвоены, даже при использовании формата связанных параметров «pyformat» (это изменение не документировано Mysqlconnector). Диалект теперь проверяет наличие py2k и mysqlconnector меньше версии 2.0 при определении того, следует ли оператор modulus отображать как
%%
или%
.This change is also backported to: 0.9.8
Unicode SQL теперь передается для MySQLconnector версии 2.0 и выше; для Py2k и MySQL < 2.0 строки кодируются.
This change is also backported to: 0.9.8
Диалект MySQL теперь поддерживает CAST для типов, построенных как объекты
TypeDecorator
.Предупреждение выдается, когда
cast()
используется с диалектом MySQL для типа, в котором MySQL не поддерживает CAST; MySQL поддерживает CAST только для некоторого подмножества типов данных. SQLAlchemy долгое время просто опускала CAST для неподдерживаемых типов в случае MySQL. Хотя мы не хотим менять это сейчас, мы выдаем предупреждение, чтобы показать, что это произошло. Предупреждение также выдается, когда CAST используется со старой версией MySQL (< 4), которая вообще не поддерживает CAST, в этом случае он также пропускается.References: #3237
Тип
SET
был переделан таким образом, чтобы больше не предполагать, что пустая строка или множество с единственным значением пустой строки на самом деле является множеством с единственной пустой строкой; вместо этого по умолчанию оно рассматривается как пустое множество. Для обработки сохранения значенийSET
, которые на самом деле хотят включить пустое значение''
в качестве легитимного значения, добавлен новый побитовый режим работы, включаемый флагомSET.retrieve_as_bitwise
, который будет сохранять и извлекать значения однозначно, используя их битовое расположение флагов. Также исправлено хранение и извлечение юникодных значений для конфигураций драйверов, не преобразующих юникод нативно.См.также
MySQL SET Type Переработан для поддержки пустых наборов, юникода, обработки пустых значений
References: #3283
Оператор
ColumnOperators.match()
теперь обрабатывается таким образом, что возвращаемый тип не считается строго булевым; теперь он возвращает подклассBoolean
, называемыйMatchType
. При использовании в выражениях Python этот тип по-прежнему будет иметь тип boolean, однако диалект может переопределять его поведение во время получения результата. В случае с MySQL, хотя оператор MATCH обычно используется в булевом контексте в выражении, при запросе значения выражения match возвращается значение с плавающей точкой, которое не совместимо с булевым процессором SQLAlchemy, основанным на языке C, поэтому поведение MySQL в наборе результатов теперь соответствует типуFloat
. Также добавлен новый объект оператораnotmatch_op
, позволяющий диалектам лучше определять отрицание операции совпадения.References: #3263
Булевые символы MySQL «true», «false» снова работают. Изменение в версии 0.9 в #2682 запретило диалекту MySQL использовать символы «true» и «false» в контексте «IS» / «IS NOT», но MySQL поддерживает этот синтаксис, хотя и не имеет типа boolean. MySQL остается «неродным булевым», но символы
true()
иfalse()
снова дают ключевые слова «true» и «false», так что выражение типаcolumn.is_(true())
снова работает в MySQL.References: #3186
Диалект MySQL теперь будет отключать события
ConnectionEvents.handle_error()
для тех операторов, которые он использует для определения существования или отсутствия таблицы. Это достигается с помощью опции выполненияskip_user_error_events
, которая отключает событие handle error для области данного выполнения. Таким образом, пользовательскому коду, переписывающему исключения, не нужно беспокоиться о диалекте MySQL или других диалектах, которые иногда должны перехватывать специфические для SQLAlchemy исключения.Изменено значение по умолчанию параметра «raise_on_warnings» на False для MySQLconnector. По какой-то причине это значение было установлено в True. Флаг «buffered», к сожалению, должен оставаться в значении True, так как MySQLconnector не позволяет закрыть курсор, пока все результаты не будут полностью получены.
References: #2515
sqlite¶
Добавлена поддержка частичных индексов (например, с предложением WHERE) на SQLite. Pull request любезно предоставлен Каем Гронером.
См.также
This change is also backported to: 0.9.9
Добавлен новый бэкэнд SQLite для бэкэнда SQLCipher. Этот бэкенд обеспечивает шифрование баз данных SQLite с помощью Python-драйвера pysqlcipher, который очень похож на драйвер pysqlite.
См.также
This change is also backported to: 0.9.9
При выборе из UNION с использованием вложенного файла базы данных драйвер pysqlite передает имена столбцов в cursor.description как „dbname.tablename.colname“, а не „tablename.colname“, как это обычно делается для UNION (заметим, что для обоих случаев должно быть просто „colname“, но мы это обходим). Логика трансляции столбцов здесь была скорректирована таким образом, чтобы получать крайний правый токен, а не второй, поэтому она работает в обоих случаях. Обходной путь предоставлен Тони Робертсом.
This change is also backported to: 0.9.8
References: #3211
Исправлена проблема с переписыванием соединений в SQLite, когда подзапрос, встроенный в скалярный подзапрос, например, в IN, получал некорректные подстановки из вложенного запроса, если внутри подзапроса присутствовали те же таблицы, что и в вложенном запросе, например, в сценарии объединенного наследования.
This change is also backported to: 0.9.7
References: #3130
Ограничения UNIQUE и FOREIGN KEY теперь полностью отражаются в SQLite как с именами, так и без них. Ранее имена внешних ключей игнорировались, а неименованные уникальные ограничения пропускались. Спасибо Джону Нельсону (Jon Nelson) за помощь в решении этой задачи.
Диалект SQLite при использовании типов
DATE
,TIME
илиDATETIME
, а также при заданииstorage_format
, который отображает только числа, в DDL отобразит эти типы какDATE_CHAR
,TIME_CHAR
иDATETIME_CHAR
, так что, несмотря на отсутствие буквенных символов в значениях, колонка все равно будет иметь «текстовое сходство». Обычно в этом нет необходимости, поскольку текстовые значения в стандартных форматах хранения уже подразумевают текст.См.также
References: #3257
SQLite теперь поддерживает отражение уникальных ограничений из временных таблиц; ранее это приводило к ошибке TypeError. Pull request любезно предоставлен Йоханнесом Эрдфельтом.
См.также
SQLite/Oracle имеют разные методы для сообщения имен временных таблиц/ представлений - изменения, касающиеся отражения временных таблиц и представлений SQLite.
References: #3203
Добавлены методы
Inspector.get_temp_table_names()
иInspector.get_temp_view_names()
; в настоящее время эти методы поддерживаются только диалектами SQLite и Oracle. Возврат имен временных таблиц и представлений был удален из версийInspector.get_table_names()
иInspector.get_view_names()
для SQLite и Oracle; другие бэкенды баз данных не могут поддерживать эту информацию (например, MySQL), а область действия отличается тем, что таблицы могут быть локальными для сессии и, как правило, не поддерживаются в удаленных схемах.References: #3204
mssql¶
Включена «многозначная вставка» для SQL Server 2008. Pull request любезно предоставлен Альбертом Кервином. Также расширены проверки для режима «IDENTITY INSERT», чтобы включить случаи, когда ключ идентификации присутствует в предложении VALUEs оператора.
This change is also backported to: 0.9.7
SQL Server 2012 теперь рекомендует использовать VARCHAR(max), NVARCHAR(max), VARBINARY(max) для больших текстовых/двоичных типов. Диалект MSSQL теперь будет учитывать это, основываясь на определении версии, а также на новом флаге
deprecate_large_types
.References: #3039
При использовании pyodbc формат подключения к SQL Server на основе имени хоста больше не будет указывать «имя драйвера» по умолчанию, а при его отсутствии будет выдаваться предупреждение. Оптимальное имя драйвера для SQL Server часто меняется и зависит от платформы, поэтому соединения на основе имени хоста должны быть указаны. Предпочтительнее использовать соединения на основе DSN.
References: #3182
Добавлена кодировка операторов «SET IDENTITY_INSERT», которые работают при явном INSERT в столбец IDENTITY, для поддержки неаскриптивных идентификаторов таблиц в драйверах типа pyodbc + unix + py2k, которые не поддерживают юникодные операторы.
This change is also backported to: 0.9.7, 0.8.7
В диалекте SQL Server pyodbc исправлена реализация параметра диалекта
description_encoding
, который при отсутствии явной установки препятствовал корректному разбору cursor.description в случае наборов результатов, содержащих имена в альтернативных кодировках. В дальнейшем этот параметр не нужен.This change is also backported to: 0.9.7, 0.8.7
References: #3091
Исправлено определение строки версии в диалекте pymssql для работы с Microsoft SQL Azure, при котором слово «SQL Server» меняется на «SQL Azure».
This change is also backported to: 0.9.8
References: #3151
Переработал запрос, используемый для определения текущего имени схемы по умолчанию, для использования функции
database_principal_id()
в сочетании с представлениемsys.database_principals
, чтобы можно было определять схему по умолчанию независимо от типа выполняемого входа в систему (например, SQL Server, Windows и т.д.).This change is also backported to: 0.9.5
References: #3025
oracle¶
Добавлена поддержка подключений cx_oracle к конкретному имени сервиса, а не к имени tns, путем передачи
?service_name=<name>
в URL. Pull request любезно предоставлен Sławomir Ehlert.Новые возможности Oracle DDL для таблиц, индексов: COMPRESS, BITMAP. Патч любезно предоставлен Габором Гомбасом.
Добавлена поддержка CTE под Oracle. Это включает в себя некоторые изменения в синтаксисе псевдонимов, а также новую функцию CTE
CTE.suffix_with()
, которая полезна для добавления в CTE специальных директив, специфичных для Oracle.См.также
References: #3220
Добавлена поддержка опции ON COMMIT для таблиц Oracle.
Исправлена давняя ошибка в диалекте Oracle, когда имена связанных параметров, начинающиеся с цифр, не заключались в кавычки, поскольку Oracle не любит цифр в именах связанных параметров.
This change is also backported to: 0.9.8
References: #2138
Исправлена ошибка в тестовом наборе oracle dialect, когда в одном из тестов предполагалось, что „username“ находится в URL базы данных, хотя это могло быть не так.
This change is also backported to: 0.9.7
References: #3128
При ссылке на псевдоним с помощью маркера
%(name)s
внутри методаSelect.with_hint()
имя будет правильно заключено в кавычки. Ранее в бэкенде Oracle такое цитирование не было реализовано.
tests¶
Исправлена ошибка, при которой команда «python setup.py test» не вызывала должным образом distutils, в результате чего в конце тестового набора выдавались ошибки.
This change is also backported to: 0.9.7
Исправлены некоторые предупреждения об устаревании, связанные с модулем
imp
и Python 3.3 или выше, при выполнении тестов. Pull request любезно предоставлен Matt Chisholm.This change is also backported to: 0.9.5
References: #2830
misc¶
Добавлен новый набор расширений
sqlalchemy.ext.baked
. Эта простая, но необычная система позволяет значительно снизить накладные расходы на Python при построении и обработке объектов ormQuery
, начиная с построения запроса и заканчивая выводом строкового SQL-оператора.См.также
References: #3054
Расширение
sqlalchemy.ext.automap
теперь будет автоматически устанавливатьcascade="all, delete-orphan"
для отношений «один-ко-многим»/обратных ссылок, в которых внешний ключ определяется как содержащий один или несколько ненулевых столбцов. Этот аргумент присутствует в ключевых словах, передаваемых вgenerate_relationship()
в этом случае и может быть переопределен. Кроме того, если вForeignKeyConstraint
указаноondelete="CASCADE"
для ненулевого илиondelete="SET NULL"
для нулевого набора столбцов, то аргументpassive_deletes=True
также добавляется к отношению. Отметим, что не все бэкенды поддерживают отражение ondelete, но такие бэкенды, как PostgreSQL и MySQL, поддерживают.References: #3210
Словарь
__mapper_args__
при обращении к нему копируется из декларативного миксина или абстрактного класса, чтобы изменения, вносимые в этот словарь самим декларативом, не конфликтовали с изменениями других маппингов. Словарь модифицируется относительно аргументовversion_id_col
иpolymorphic_on
, заменяя в нем столбец на тот, который официально отображен на локальный класс/таблицу.This change is also backported to: 0.9.5, 0.8.7
References: #3062
Исправлена ошибка в мутабельном расширении, когда
MutableDict
не сообщал о событиях изменения для операции со словаремsetdefault()
.This change is also backported to: 0.9.5, 0.8.7
Исправлена ошибка, при которой
MutableDict.setdefault()
не возвращало существующее или новое значение (эта ошибка не встречалась ни в одной из версий 0.8). Pull request любезно предоставлен Томасом Эрве.This change is also backported to: 0.9.5, 0.8.7
Исправлена ошибка, из-за которой класс association proxy list некорректно интерпретировал срезы под Py3K. Pull request любезно предоставлен Gilles Dartiguelongue.
This change is also backported to: 0.9.9
Исправлено маловероятное состояние гонки, наблюдавшееся при некоторых экзотических настройках конечных пользователей, когда при попытке проверки на «дублирование имени класса» в декларативной форме можно было наткнуться на не полностью очищенную слабую ссылку, относящуюся к другому удаляемому классу; теперь проверка здесь гарантирует, что слабая ссылка все еще ссылается на объект перед дальнейшим обращением к нему.
This change is also backported to: 0.9.8
References: #3208
Исправлена ошибка в списке упорядочивания, когда порядок элементов сбивался при событии замены коллекции, если флаг reorder_on_append был установлен в True. Исправление гарантирует, что список упорядочивания влияет только на тот список, который явно ассоциирован с объектом.
This change is also backported to: 0.9.8
References: #3191
Исправлена ошибка, при которой в
MutableDict
не реализовывался метод словаряupdate()
, в результате чего не перехватывались изменения. Pull request любезно предоставлен Matt Chisholm.This change is also backported to: 0.9.8
Исправлена ошибка, при которой пользовательский подкласс
MutableDict
не отображался в операции «coerce», а вместо него возвращался обычныйMutableDict
. Pull request любезно предоставлен Matt Chisholm.This change is also backported to: 0.9.8
Исправлена ошибка в логировании пула соединений, при которой отладочное сообщение «соединение проверено» не выдавалось, если логирование было настроено с использованием флага
logging.setLevel()
, а не с использованием флагаecho_pool
. Добавлены тесты для проверки этого протоколирования. Это регрессия, которая была внесена в 0.9.0.This change is also backported to: 0.9.8
References: #3168
Исправлена ошибка, когда декларативный флаг
__abstract__
не различался, если на самом деле он имел значениеFalse
. Флаг__abstract__
должен действительно оцениваться как значение True на тестируемом уровне.This change is also backported to: 0.9.7
References: #3097
В публичном тестовом наборе изменено использование
String(40)
с менее поддерживаемогоText
вStringTest.test_literal_backslashes
. Pullreq любезно предоставлен Яном.This change is also backported to: 0.9.5
Диалект Drizzle был удален из Core; теперь он доступен в виде sqlalchemy-drizzle, независимого диалекта сторонних разработчиков. Диалект по-прежнему практически полностью основан на диалекте MySQL, присутствующем в SQLAlchemy.