0.8 Changelog¶
0.8.7¶
Released: July 22, 2014orm¶
Исправлена ошибка в ускоренной загрузке подзапросов, когда длинная цепочка ускоренных загрузок через границу полиморфный-подкласс в сочетании с полиморфной загрузкой не находила ссылку на подкласс в цепочке, выдавая ошибку с отсутствием имени свойства на
AliasedClass
.References: #3055
Исправлена ошибка ORM, когда функция
class_mapper()
маскировала ошибки AttributeErrors или KeyErrors, которые должны были возникать при конфигурировании маппера из-за ошибок пользователя. Перехват ошибок атрибутов/ключей стал более конкретным и не включает шаг конфигурирования.References: #3047
sql¶
Исправлена ошибка в
Enum
и других подклассахSchemaType
, когда прямое связывание типа сMetaData
приводило к зависанию, когда наMetaData
выдавались события (например, события create).References: #3124
Исправлена ошибка в системе пользовательских операторов плюс
TypeEngine.with_variant()
, при которой использованиеTypeDecorator
в сочетании с variant приводило к ошибке MRO при использовании оператора сравнения.References: #3102
Исправлена ошибка в конструкции INSERT..FROM SELECT, когда при выборе из UNION объединение заворачивалось в анонимный (например, немаркированный) подзапрос.
References: #3044
Исправлена ошибка, при которой
Table.update()
иTable.delete()
выдавали пустое предложение WHERE, когда применялись пустыеand_()
,or_()
или другие пустые выражения. Теперь это соответствует таковому дляselect()
.References: #3045
postgresql¶
Добавлен флаг
hashable=False
для типа PGHSTORE
, необходимый для того, чтобы ORM могла пропустить попытку «хеширования» колонки HSTORE, отображенной на ORM, при запросе ее в смешанном списке колонок/сущностей. Исправление любезно предоставлено Gunnlaugur Þór Briem.References: #3053
Добавлено новое сообщение «disconnect» - «соединение было закрыто неожиданно». По-видимому, это связано с новыми версиями SSL. Pull request любезно предоставлен Antti Haapala.
mysql¶
Ошибка MySQL 2014 «Commands out of sync» в современных версиях MySQL-Python выдается как ProgrammingError, а не OperationalError; все коды ошибок MySQL, проверяемые на «is disconnect», теперь проверяются в рамках OperationalError и ProgrammingError независимо друг от друга.
References: #3101
Исправлена ошибка, при которой имена столбцов, добавляемые в параметр
mysql_length
в индексе, для распознавания должны были иметь одинаковые кавычки для имен, взятых в кавычки. Исправление делает кавычки необязательными, но при этом сохраняет прежнее поведение для обратной совместимости с теми, кто использует обходной путь.References: #3085
Добавлена поддержка отражения таблиц, индекс которых включает KEY_BLOCK_SIZE, с помощью знака равенства. Pull request любезно предоставлен Шоном Макгиверном (Sean McGivern).
mssql¶
Добавлена кодировка операторов «SET IDENTITY_INSERT», которые работают при явном INSERT в столбец IDENTITY, для поддержки неаскриптивных идентификаторов таблиц в драйверах типа pyodbc + unix + py2k, которые не поддерживают юникодные операторы.
В диалекте SQL Server pyodbc исправлена реализация параметра диалекта
description_encoding
, который при отсутствии явной установки препятствовал корректному разбору cursor.description в случае наборов результатов, содержащих имена в альтернативных кодировках. В дальнейшем этот параметр не нужен.References: #3091
misc¶
Словарь
__mapper_args__
при обращении к нему копируется из декларативного миксина или абстрактного класса, чтобы модификации, вносимые в этот словарь самим декларативом, не конфликтовали с модификациями других отображений. Словарь модифицируется относительно аргументовversion_id_col
иpolymorphic_on
, заменяя в нем столбец на тот, который официально отображен на локальный класс/таблицу.References: #3062
Исправлена ошибка в мутабельном расширении, когда
MutableDict
не сообщал о событиях изменения для операции со словаремsetdefault()
.Исправлена ошибка, при которой
MutableDict.setdefault()
не возвращало существующее или новое значение (эта ошибка не встречалась ни в одной из версий 0.8). Pull request любезно предоставлен Томасом Эрве.
0.8.6¶
Released: March 28, 2014general¶
Скорректирован файл
setup.py
для поддержки возможного удаления в будущем расширенияsetuptools.Feature
из setuptools. Если это ключевое слово отсутствует, то установка все равно будет выполняться с помощью setuptools, а не возвращаться к distutils. Сборка расширений C теперь также может быть отключена установкой переменной окружения DISABLE_SQLALCHEMY_CEXT. Эта переменная работает независимо от наличия или отсутствия setuptools.References: #2986
orm¶
Исправлена ошибка ORM, когда при изменении первичного ключа объекта с последующей пометкой его для DELETE не удавалось выбрать правильную строку для DELETE.
References: #3006
Исправлена регрессия из 0.8.3, в результате которой #2818, где
Query.exists()
не работал в запросе, содержащем только записьQuery.select_from()
, но не имеющем других сущностей.References: #2995
Улучшено сообщение об ошибке, которая возникала, если при выполнении запроса query() к невыбираемому элементу, например,
literal_column()
, была предпринята попытка использоватьQuery.join()
таким образом, что «левая» сторона определялась какNone
, а затем происходил сбой. Теперь это условие выявляется явно.Удалены устаревшие имена из
sqlalchemy.orm.interfaces.__all__
и обновлены актуальными, так чтоimport *
из этого модуля снова работает.References: #2975
sql¶
Исправлена ошибка в конструкции
tuple_()
, когда «тип» по сути первого выражения SQL применялся в качестве «типа сравнения» к сравниваемому значению кортежа; в некоторых случаях это приводило к некорректному «принуждению к типу», например, когда кортеж, содержащий смесь значений String и Binary, некорректно принуждает целевые значения к Binary, даже если они не являются таковыми в левой части.tuple_()
теперь ожидает неоднородные типы в списке значений.References: #2977
postgresql¶
Включена проверка «вменяемого многорядного счета» для psycopg2 DBAPI, так как, похоже, она поддерживается начиная с psycopg2 2.0.9.
Исправлена регрессия, вызванная улучшениями совместимости в релизах 0.8.5 / 0.9.3, в результате которой снова нарушалось отражение индексов в PostgreSQL версий, характерных только для серий 8.1, 8.2, в том числе и для всегда проблемного типа int2vector. Если в версии 8.1 тип int2vector поддерживает операции с массивами, то в версии 8.3 он, по-видимому, поддерживает только CAST к varchar.
References: #3000
misc¶
Исправлена ошибка в мутабельном расширении, а также
flag_modified()
, когда событие изменения не распространялось, если атрибут был переназначен на себя.References: #2997
0.8.5¶
Released: February 19, 2014orm¶
Исправлена ошибка, при которой при вызове запроса с существующим критерием
Query.get()
не удавалось последовательно поднять , вызывающийInvalidRequestError
, если заданный идентификатор уже присутствует в карте идентификаторов.References: #2951
Исправлено сообщение об ошибке при передаче объекта-итератора в
class_mapper()
или аналогичное, когда ошибка не выводилась при форматировании строки. Pullreq любезно предоставлен Кайлом Старком.Корректировка стратегии
subqueryload()
, которая обеспечивает выполнение запроса после начала загрузки; это сделано для того, чтобы загрузка подзапроса имела приоритет перед другими загрузчиками, которые могут попасть на тот же атрибут из-за других ситуаций eager/noload в неподходящее время.References: #2887
Исправлена ошибка, когда при использовании наследования объединенной таблицы из таблицы в select/alias на базе, где столбцы PK также не имели одинаковых имен, система персистентности не могла скопировать значения первичного ключа из базовой таблицы в унаследованную таблицу при INSERT.
References: #2885
composite()
будет выдано информативное сообщение об ошибке, если переданные столбцы/атрибуты (имена) не разрешаются в столбец или сопоставленный атрибут (например, ошибочный кортеж); ранее выдавалось несвязанное локальное сообщение.References: #2889
engine¶
Исправлена критическая регрессия, вызванная #2880, когда новая возможность одновременного возврата соединений из пула означает, что событие «first_connect» теперь также не синхронизируется, что приводит к неправильной конфигурации диалекта даже в ситуациях с минимальным параллелизмом.
sql¶
Исправлена ошибка, при которой вызов
Insert.values()
с пустым списком или кортежем приводил к ошибке IndexError. Теперь он выдает пустую конструкцию вставки, как это было бы в случае с пустым словарем.References: #2944
Исправлена ошибка, когда при ошибочной передаче выражения столбца, компаратор которого включает метод
__getitem__()
, например, столбца, использующего типARRAY
,ColumnOperators.in_()
, происходил бесконечный цикл.References: #2957
Исправлена проблема, при которой столбец с первичным ключом, на который наложена последовательность, но при этом столбец не является столбцом с «автоматическим инкрементом», поскольку на него наложено ограничение внешнего ключа или установлено значение
autoincrement=False
, пытался сработать при INSERT для бэкендов, не поддерживающих последовательности, при представлении INSERT с отсутствием значения первичного ключа. Это происходит на бэкендах, не поддерживающих последовательности, таких как SQLite, MySQL.References: #2896
Исправлена ошибка в методе
Insert.from_select()
, когда при генерации оператора INSERT не учитывался порядок следования заданных имен, что приводило к несовпадению с именами столбцов в заданном операторе SELECT. Также отмечено, чтоInsert.from_select()
подразумевает невозможность использования стандартных параметров вставки на стороне Python, так как в операторе отсутствует предложение VALUES.References: #2895
Исключение, возникающее при наличии в скомпилированном операторе символа
BindParameter
без значения, теперь включает в сообщение об ошибке имя ключа связанного параметра.
postgresql¶
В обнаружение отключения psycopg2 добавлено дополнительное сообщение «не удалось отправить данные на сервер», которое дополняет существующее «не удалось получить данные с сервера» и было замечено пользователями.
References: #2936
Улучшена поддержка поведения отражения PostgreSQL на очень старых (до 8.1) версиях PostgreSQL и, возможно, на других PG-движках, таких как Redshift (при условии, что Redshift сообщает версию < 8.1). Запрос на «индексы» и «первичные ключи» основан на проверке так называемого типа данных «int2vector», который до версии 8.1 отказывается преобразовываться в массив, что приводит к сбоям в работе оператора «ANY()», используемого в запросе. В результате длительного гугления был найден очень хакерский, но рекомендованный разработчиками PG-core запрос, который следует использовать при использовании PG версии < 8.1, поэтому отражение ограничений по индексу и первичному ключу теперь работает на этих версиях.
Переработан очень старый вопрос, в котором запрос отражения PostgreSQL «get primary key» был обновлен для учета ограничений первичного ключа, которые были переименованы; новый запрос не работает на очень старых версиях PostgreSQL, таких как версия 7, поэтому старый запрос восстанавливается в тех случаях, когда обнаружена server_version_info < (8, 0).
References: #2291
mysql¶
Добавлена новая специфичная для MySQL функция
DATETIME
, включающая поддержку дробных секунд; также добавлена поддержка дробных секунд вTIMESTAMP
. Поддержка DBAPI ограничена, хотя известно, что дробные секунды поддерживаются MySQL Connector/Python. Патч любезно предоставлен Geert JM Vanderkelen.References: #2941
Добавлена поддержка ключевых слов таблиц MySQL
PARTITION BY
иPARTITIONS
, указанных какmysql_partition_by='value'
иmysql_partitions='value'
-Table
. Pull request любезно предоставлен Маркусом МакКерди.References: #2966
Исправлена ошибка, не позволявшая диалектам на основе MySQLdb (например, pymysql) работать в Py3K, когда проверка на «connection charset» не выполнялась из-за более строгих правил сравнения значений в Py3K. В данном случае версия базы данных не учитывалась, так как версия сервера на тот момент была еще None, поэтому метод в целом был упрощен и теперь полагается на connection.character_set_name().
References: #2933
В диалект cymysql добавлены некоторые недостающие методы, включая _get_server_version_info() и _detect_charset(). Pullreq любезно предоставлен Хаджиме Накагами (Hajime Nakagami).
sqlite¶
Восстановлено изменение, пропущенное при бэкпорте отражения уникальных ограничений в 0.8, когда при включении в имена столбцов зарезервированных ключевых слов происходила ошибка
UniqueConstraint
с SQLite. Pull request любезно предоставлен Романом Подолякой.
mssql¶
Флаг «asdecimal», используемый с типом
Float
, теперь будет работать как с Firebird, так и с диалектами mssql+pyodbc; ранее десятичное преобразование не происходило.В список сообщений, проверяемых на «разъединение» в диалекте pymssql, добавлено сообщение «Net-Lib error during Connection reset by peer». Предоставлено Джоном Андерсоном.
misc¶
Исправлена ошибка Py3K, при которой отсутствие импорта приводило к тому, что режим «literal binary» не импортировал «util.binary_type» при визуализации связанного параметра. В 0.9 это решается по-другому. Pull request любезно предоставлен Андреасом Цайдлером.
Диалект firebird будет заключать в кавычки идентификаторы, начинающиеся с символа подчеркивания. Любезно предоставлено Treeve Jelbert.
References: #2897
Исправлена ошибка в отражении индекса Firebird, когда столбцы внутри индекса сортировались неправильно; теперь они сортируются в порядке RDB$FIELD_POSITION.
Сообщение об ошибке при получении строкового аргумента
relationship()
, не разрешающегося в класс или mapper, исправлено на такое же, как и при получении нестрокового аргумента, который указывает имя отношения, в котором произошла конфигурационная ошибка.References: #2888
0.8.4¶
Released: December 8, 2013orm¶
engine¶
DBAPI, вызывающий ошибку в
connect()
, не являющийся подклассом dbapi.Error (например,TypeError
,NotImplementedError
и т.д.), будет распространять исключение без изменений. Ранее при обработке ошибок, характерной для подпрограммыconnect()
, исключение неадекватно проходило через подпрограмму диалектаDialect.is_disconnect()
, а также заворачивалось вsqlalchemy.exc.DBAPIError
. Теперь оно передается без изменений так же, как это происходит в процессе выполнения.References: #2881
Функция
QueuePool
была усовершенствована таким образом, чтобы не блокировать новые попытки соединения, если существующая попытка соединения блокируется. Ранее создание новых соединений было сериализовано в блоке, контролирующем переполнение; теперь счетчик переполнения изменяется в собственной критической секции вне самого процесса соединения.References: #2880
Внесена небольшая корректировка в логику ожидания доступности пула соединений: для пула соединений, таймаут которого не указан, он будет каждые полсекунды прерывать ожидание для проверки наличия так называемого флага «abort», который позволяет официанту прервать ожидание в случае сброса всего пула соединений; обычно официант должен прерваться из-за уведомления notify_all(), но в очень редких случаях возможно, что уведомление notify_all() пропущено. Это расширение логики, впервые представленной в 0.8.0, и проблема наблюдалась лишь изредка в стресс-тестах.
References: #2522
Исправлена ошибка, при которой SQL-оператор неправильно кодировался в ASCII-коде, когда внутри
Connection.execute()
поднимался pre-DBAPIStatementError
, что приводило к ошибкам кодировки для не-ASCII-операторов. Теперь строчная кодировка остается в рамках юникода Python, что позволяет избежать ошибок кодировки.References: #2871
sql¶
Добавлена поддержка отражения «уникальных ограничений» с помощью метода
Inspector.get_unique_constraints()
. Спасибо Роману Подоляке за патч.References: #1443
postgresql¶
Исправлена ошибка, из-за которой при использовании адаптера pypostgresql, возвращающего значения indkey в виде списков, а в psycopg2 возвращающего тип string, отражение индексов неверно интерпретировало значения indkey.
References: #2855
mssql¶
Исправлена ошибка, появившаяся в 0.8.0, когда оператор
DROP INDEX
для индекса в MSSQL отображался некорректно, если индекс находился в альтернативной схеме; имя схемы/таблицы менялось на противоположное. Формат также был изменен, чтобы соответствовать текущей документации по MSSQL. Любезно предоставлено Дереком Харландом.
oracle¶
misc¶
Исправлена ошибка, из-за которой расширение
serializer
не могло корректно работать с именами таблиц и столбцов, содержащими не ASCII-символы.References: #2869
0.8.3¶
Released: October 26, 2013orm¶
Добавлена новая опция к
relationship()
distinct_target_key
. Это позволяет стратегии ускоренной загрузки подзапросов применять DISTINCT к самому внутреннему подзапросу SELECT, чтобы помочь в случае, когда дублирующиеся строки генерируются самым внутренним запросом, соответствующим этому отношению (пока не существует общего решения проблемы дублирующихся строк в рамках ускоренной загрузки подзапросов, однако, когда соединения вне самого внутреннего подзапроса создают дубликаты). Если флаг установлен в значениеTrue
, то DISTINCT выводится безусловно, а если в значениеNone
, то DISTINCT выводится, если внутреннее отношение касается столбцов, не составляющих полный первичный ключ. По умолчанию в 0.8 опция имеет значение False (т.е. по умолчанию отключена во всех случаях), в 0.9 - None (т.е. по умолчанию работает автоматически). Спасибо Александру Ковалю за помощь в этом вопросе.См.также
Подзапрос Eager Loading будет применять DISTINCT к самому внутреннему SELECT для некоторых запросов
References: #2836
Исправлена ошибка, из-за которой инструментарий списков не мог корректно представить фрагмент множества
[0:0]
, что, в частности, могло происходить при использованииinsert(0, item)
с прокси ассоциации. Из-за некоторой причуды в коллекциях Python эта проблема была гораздо более вероятна в Python 3, а не 2.This change is also backported to: 0.7.11
References: #2807
Исправлена ошибка, при которой использование аннотации типа
remote()
илиforeign()
вColumn
перед объединением с родительскойTable
могло привести к проблемам, связанным с тем, что родительская таблица не отображалась в джойнах, из-за присущей аннотации операции копирования.References: #2813
Исправлена ошибка, при которой
Query.exists()
не работал корректно без критерия WHERE. Любезно предоставлено Владимиром Магамедовым.References: #2818
В 0.9 перенесено изменение, позволяющее сортировать итерации иерархии мапперов, используемых при загрузке полиморфного наследования, что обеспечивает детерминированный рендеринг операторов SELECT, генерируемых для полиморфных запросов, что в свою очередь помогает при использовании схем кэширования, кэширующих саму строку SQL.
References: #2779
Исправлена потенциальная проблема в реализации упорядоченной последовательности, используемой в ORM для итерации иерархий картографов; в интерпретаторе Jython эта реализация не была упорядочена, хотя cPython и PyPy поддерживали упорядочивание.
References: #2794
Исправлена ошибка в регистрации событий на уровне ORM, когда флаги «raw» или «propagate» могли быть неправильно настроены в некоторых конфигурациях «unmapped base class».
References: #2786
Исправление производительности, связанное с использованием опции
defer()
при загрузке отображаемых сущностей. Накладные расходы на выполнение функций при применении отложенного вызова для каждого объекта к экземпляру во время загрузки были значительно выше, чем при простой загрузке данных из строки (обратите внимание, чтоdefer()
предназначена для снижения накладных расходов на работу с БД/сетью, а не на количество вызовов функций); теперь накладные расходы на вызов функций во всех случаях меньше, чем при загрузке данных из столбца. Также уменьшилось количество «лениво вызываемых» объектов, создаваемых при загрузке, с N (общее количество отложенных значений в результате) до 1 (общее количество отложенных столбцов).References: #2778
Исправлена ошибка, из-за которой при переводе объекта из состояния «persistent» в состояние «pending» с помощью функции
make_transient()
для операций с обратными ссылками на основе коллекций происходил сбой функций истории атрибутов.References: #2773
orm declarative¶
Добавлен удобный декоратор классов
as_declarative()
, представляющий собой обертку дляdeclarative_base()
, которая позволяет применить существующий базовый класс, используя удобный класс-декоратор.
examples¶
Улучшены примеры в
examples/generic_associations
, в частности, вdiscriminator_on_association.py
используется наследование одной таблицы для работы с «дискриминатором». Также добавлен пример настоящего «общего внешнего ключа», который работает аналогично другим популярным фреймворкам, поскольку использует неограниченное целое число для указания на любую другую таблицу, отказываясь от традиционной ссылочной целостности. Хотя мы не рекомендуем использовать этот паттерн, информация хочет быть свободной.Добавлена опция «autoincrement=False» в таблицу history, созданную в примере с версионированием, так как в этой таблице в любом случае не должно быть autoinc, любезно предоставлено Патриком Шмидом.
engine¶
repr()
дляURL
изEngine
теперь будет скрывать пароль с помощью звездочек. Предоставлено Gunnlaugur Þór Briem.References: #2821
Regexp, используемый функцией
make_url()
, теперь разбирает ipv6-адреса, например, окруженные скобками.This change is also backported to: 0.7.11
References: #2851
Dialect.initialize() не вызывается второй раз, если
Engine
пересоздается из-за ошибки разъединения. Это устраняет конкретную проблему в диалекте Oracle 8, но в целом фаза dialect.initialize() должна выполняться только один раз для каждого диалекта.References: #2776
Исправлена ошибка, при которой
QueuePool
терял корректный счетчик проверенных соединений, если существующее пул-соединение не удавалось переподключить после события invalidate или recycle.References: #2772
sql¶
Добавлен новый метод в конструкцию
insert()
Insert.from_select()
. Учитывая список столбцов и возможность выбора, выводитINSERT INTO (table) (columns) SELECT ..
.References: #722
Конструкции
update()
,insert()
иdelete()
теперь будут интерпретировать сущности ORM как целевые таблицы, с которыми нужно работать, например:from sqlalchemy import insert, update, delete ins = insert(SomeMappedClass).values(x=5) del_ = delete(SomeMappedClass).where(SomeMappedClass.id == 5) upd = update(SomeMappedClass).where(SomeMappedClass.id == 5).values(name="ed")
Исправлена ошибка, восходящая к 0.7.9, в результате которой имя CTE могло не заключаться в кавычки, если на него ссылались в нескольких предложениях FROM.
This change is also backported to: 0.7.11
References: #2801
Исправлена ошибка в системе общих табличных выражений, когда если CTE использовался только как конструкция
alias()
, то при использовании ключевого слова WITH он не выводился.This change is also backported to: 0.7.11
References: #2783
Исправлена ошибка в DDL
CheckConstraint
, когда флаг «quote» из объектаColumn
не распространялся.This change is also backported to: 0.7.11
References: #2784
Исправлена ошибка, при которой
type_coerce()
не интерпретировал должным образом элементы ORM с методом__clause_element__()
.References: #2849
Типы
Enum
иBoolean
теперь обходят любой пользовательский (например, TypeDecorator) тип, используемый при создании ограничения CHECK для «неродного» типа. Таким образом, пользовательский тип не участвует в выражении внутри CHECK, поскольку это выражение относится к значению «impl», а не к значению «decorated».References: #2842
Флаг
.unique
вIndex
мог быть выдан какNone
, если он был сгенерирован изColumn
, в котором не было указаноunique
(где по умолчанию стоитNone
). Теперь флаг всегда будетTrue
илиFalse
.References: #2825
Исправлена ошибка в компиляторе по умолчанию, а также в компиляторах postgresql, mysql и mssql, в результате которой в операторе CREATE INDEX любые литеральные значения SQL-выражений отображаются непосредственно как литералы, а не как связанные параметры. Это также изменяет схему рендеринга для других DDL, таких как ограничения.
References: #2742
select()
, который в предложении FROM ссылается сам на себя, как правило, с помощью мутации на месте, будет выдавать информативное сообщение об ошибке, а не вызывать переполнение рекурсии.References: #2815
Нерабочий аргумент «schema» в
ForeignKey
является устаревшим; выдает предупреждение. Удален в 0.9.References: #2831
Исправлена ошибка, при которой использование события
column_reflect
для изменения.key
входящегоColumn
приводило к некорректному отражению ограничений первичного ключа, индексов и ограничений внешнего ключа.References: #2811
Оператор
ColumnOperators.notin_()
, добавленный в 0.8, теперь корректно выдает отрицание выражения «IN», возвращаемого при использовании против пустой коллекции.Исправлена ошибка, когда при обращении к коллекции
.c
в конструкцииselect()
система выражений полагалась на формуstr()
некоторых выражений, но формаstr()
была недоступна, поскольку элемент опирался на диалектные конструкции компиляции, в частности, на оператор__getitem__()
, используемый с элементом PostgreSQLARRAY
. Исправление также добавляет новый класс исключенийUnsupportedCompilationError
, который возникает в тех случаях, когда компилятору предлагается скомпилировать то, что он не умеет.References: #2780
postgresql¶
Убрано 128-символьное усечение из отражения серверного значения по умолчанию для колонки; этот код был исходным для системных представлений PG, которые усекали строку для удобочитаемости.
References: #2844
Скобки будут применяться к составному SQL-выражению, отображаемому в списке столбцов оператора CREATE INDEX.
References: #2742
Исправлена ошибка, из-за которой строки версий PostgreSQL, содержащие префикс перед словами «PostgreSQL» или «EnterpriseDB», не обрабатывались. Предоставлено Скоттом Шефером.
References: #2819
mysql¶
Обновления зарезервированных слов MySQL для версий 5.5, 5.6, любезно предоставленные Ханно Шлихтингом (Hanno Schlichting).
This change is also backported to: 0.7.11
References: #2791
Изменение в #2721, заключающееся в том, что ключевое слово
deferrable
вForeignKeyConstraint
молча игнорируется бэкендом MySQL, будет отменено в версии 0.9; теперь это ключевое слово будет снова отображаться, вызывая ошибки в MySQL, поскольку оно не понимается - такое же поведение будет и для ключевого словаinitially
. В 0.8 ключевые слова по-прежнему игнорируются, но выдается предупреждение. Кроме того, ключевое словоmatch
теперь вызывает ошибкуCompileError
в 0.9 и предупреждение в 0.8; это ключевое слово не только молча игнорируется MySQL, но и нарушает работу опций ON UPDATE/ON DELETE.Чтобы использовать
ForeignKeyConstraint
, который не рендерится или рендерится по-другому на MySQL, используйте пользовательскую опцию компиляции. Пример такого использования добавлен в документацию, смотрите Внешние ключи MySQL / MariaDB.Диалект MySQL-connector теперь позволяет опциям в строке запроса create_engine переопределять значения по умолчанию, установленные в connect, включая «buffered» и «raise_on_warnings».
References: #2515
sqlite¶
Недавно добавленные в SQLite DATETIME аргументы storage_format и regexp, по-видимому, были реализованы не совсем корректно; хотя аргументы и принимались, на практике они не оказывали никакого влияния; это исправлено.
References: #2781
oracle¶
Исправлена ошибка, при которой отражение таблиц Oracle с использованием синонимов приводило к ошибке, если синоним и таблица находились в разных удаленных схемах. Патч для исправления предоставлен Кайлом Дерром.
References: #2853
misc¶
К
Column
добавлен новый флагsystem=True
, который помечает столбец как «системный», автоматически предоставляемый базой данных (например, PostgreSQLoid
илиxmin
). Столбец будет опущен в оператореCREATE TABLE
, но в остальном будет доступен для запросов. Кроме того, конструкцияCreateColumn
может быть применена к пользовательскому правилу компиляции, которое позволяет пропускать столбцы, создавая правило, возвращающееNone
.
0.8.2¶
Released: July 3, 2013orm¶
Добавлен новый метод
Query.select_entity_from()
, который в 0.9 частично заменит функциональностьQuery.select_from()
. В 0.8 эти два метода выполняют одну и ту же функцию, поэтому при необходимости код может быть переведен на использование методаQuery.select_entity_from()
. Подробности см. в руководстве по миграции в 0.9.References: #2736
Предупреждение выдается при попытке прошить объект унаследованного класса, в котором полиморфному дискриминатору было присвоено значение, недопустимое для данного класса.
References: #2750
Исправлена ошибка в генерации полиморфного SQL, когда несколько сущностей с объединенным наследованием против одного и того же базового класса, объединенных друг с другом, не отслеживали колонки базовой таблицы независимо друг от друга, если длина строки объединений превышала две сущности.
References: #2759
Исправлена ошибка, когда при передаче составного атрибута в
Query.order_by()
получалось выражение в круглых скобках, не принимаемое некоторыми базами данных.References: #2754
Исправлено взаимодействие составных атрибутов с функцией
aliased()
. Ранее составные атрибуты некорректно работали в операциях сравнения, когда применялось выравнивание.References: #2755
Исправлена ошибка, при которой
MutableDict
не сообщал о событии изменения при вызовеclear()
.References: #2730
Исправлена регрессия, вызванная #2682, в результате которой оценка, вызванная
Query.update()
иQuery.delete()
, наталкивалась на неподдерживаемые символыTrue
иFalse
, которые теперь появляются из-за использованияIS
.References: #2737
Исправлена регрессия из 0.7, вызванная этим тикетом, которая делала проверку на переполнение рекурсии в самореферентных eager joining слишком слабой, упуская конкретный случай, когда подкласс имел настройки lazy=»joined» или «subquery», а загрузка была «with_polymorphic» по отношению к базе.
References: #2481
В 0.7 исправлена ошибка, из-за которой функция контекстного менеджера
Session.begin_nested()
не могла корректно откатить транзакцию при возникновении ошибки flush, вместо этого вызывая собственное исключение, оставляя сессию в ожидании отката.References: #2718
orm declarative¶
На дескрипторы ORM, такие как гибридные свойства, теперь можно ссылаться по имени в строковом аргументе, используемом с
order_by
,primaryjoin
или аналогичном вrelationship()
, в дополнение к атрибутам, связанным с колонками.References: #2761
examples¶
Исправлена проблема, связанная с рецептом «версионирования», когда при наличии обратных ссылок ссылка «многие к одному» могла приводить к бессмысленной версии для цели, даже если она не была изменена. Исправление любезно предоставлено Мэттом Чисхолмом.
Исправлена небольшая ошибка в примере dogpile, когда генерация ключей кэша SQL не применяла метки дедупирования к оператору так, как это обычно делает
Query
.
engine¶
Исправлена ошибка, при которой аргумент
reset_on_return
в различных реализацияхPool
не распространялся при регенерации пула. Предоставлено Eevee.Исправлена ошибка, из-за которой процедура определения правильных kwargs, передаваемых в
create_engine()
, в некоторых случаях, например, при работе с диалектом Sybase, не работала.References: #2732
sql¶
Предоставлен новый атрибут для
TypeDecorator
, называемыйTypeDecorator.coerce_to_is_types
, для облегчения управления тем, как сравнение с помощью==
или!=
сNone
и булевыми типами выдает выражениеIS
или обычное выражение равенства со связанным параметром.Многочисленные исправления корреляционного поведения конструкций
Select
, впервые появившиеся в 0.8.0:Для того чтобы удовлетворить условиям использования, когда записи FROM должны коррелировать по направлению к SELECT, который включает в себя другой, который затем включает в себя этот, корреляция теперь работает на нескольких уровнях, когда явная корреляция устанавливается с помощью
Select.correlate()
, при условии, что целевой select находится где-то в цепочке, содержащейся в предложении WHERE/ORDER BY/columns, а не только во вложенных предложениях FROM. Таким образом, поведениеSelect.correlate()
стало более совместимым с 0.7, сохранив при этом новую «умную» корреляцию.Когда явная корреляция не используется, обычная «неявная» корреляция ограничивает свое поведение только непосредственным вложением SELECT, чтобы максимизировать совместимость с приложениями 0.7, а также предотвращает корреляцию между вложенными FROM в этом случае, поддерживая совместимость с 0.8.0/0.8.1.
Метод
Select.correlate_except()
не во всех случаях предотвращал корреляцию заданных предложений FROM, а также приводил к некорректному опусканию предложений FROM (более похоже на то, как это было в 0.7), что было исправлено.Вызов select.correlate_except(None) введет в корреляцию все предложения FROM, как и следовало ожидать.
Исправлена ошибка, при которой при присоединении select() таблицы «A» с несколькими путями внешних ключей к таблице «B» к этой таблице «B» не выдавалась ошибка «неоднозначное условие присоединения», которая выдается при присоединении таблицы «A» непосредственно к «B»; вместо этого выдавалось условие присоединения с несколькими критериями.
References: #2738
Исправлена ошибка, из-за которой использование
MetaData.reflect()
как в удаленной, так и в локальной схеме могло приводить к неверным результатам в случае, когда обе схемы имели таблицу с одинаковым именем.References: #2728
Убран вызов
__iter__()
из базового классаColumnOperators
, который был введен в 0.8.0 для предотвращения бесконечного, увеличивающего память цикла, когда пользователь также реализует метод__getitem__()
для пользовательского оператора и затем ошибочно вызываетlist()
для этого объекта, но это приводило к тому, что элементы столбцов сообщали, что они на самом деле являются итерируемыми типами, которые затем выдавали ошибку при попытке выполнить итерацию. В данном случае нет реального способа получить обе стороны, поэтому мы придерживаемся лучших практик Python. Осторожнее с реализацией__getitem__()
в пользовательских операторах!References: #2726
Регрессия из этого тикета привела к появлению неподдерживаемого ключевого слова «true», добавлена логика для преобразования этого значения в 1/0 для SQL-сервера.
References: #2682
postgresql¶
Добавлена поддержка типов диапазонов PostgreSQL 9.2. В настоящее время трансляция типов не предусмотрена, поэтому в данный момент работа ведется напрямую со строками или типами расширения диапазона psycopg2 2.5. Патч любезно предоставлен Крисом Уитерсом.
Добавлена поддержка изоляции «AUTOCOMMIT» при использовании psycopg2 DBAPI. Ключевое слово доступно через опцию выполнения
isolation_level
. Патч любезно предоставлен Романом Подолякой.References: #2072
Поведение
extract()
было упрощено на диалекте PostgreSQL, чтобы больше не вводить в данное выражение жестко закодированный::timestamp
или аналогичный каст, поскольку это мешало работе с такими типами, как timezone-aware datetimes, а также не было необходимо в современных версиях psycopg2.References: #2740
Исправлена ошибка в типе HSTORE, когда ключи/значения, содержащие кавычки с обратным слешем, не экранировались корректно при использовании «неродных» (т.е. не-psycopg2) средств трансляции данных HSTORE. Исправление любезно предоставлено Райаном Келли.
References: #2766
Исправлена ошибка, при которой порядок колонок в многоколоночном индексе PostgreSQL отражался в неправильном порядке. Любезно предоставлено Романом Подолякой.
References: #2767
Исправлен тип HSTORE для корректного кодирования/декодирования для юникода. Это всегда включено, так как hstore является текстовым типом, и соответствует поведению psycopg2 при использовании Python 3. Предоставлено Дмитрием Мугтасимовым.
References: #2735
mysql¶
Параметр
mysql_length
, используемый сIndex
, теперь может передаваться в виде словаря имен/длины столбцов, что позволяет использовать его с составными индексами. Большая благодарность Роману Подоляке за патч.References: #2704
Исправлена ошибка, когда при использовании многотабличного UPDATE, где дополнительная таблица представляет собой SELECT с собственными связанными параметрами, при использовании специального синтаксиса MySQL позиционирование связанных параметров было обратным по отношению к самому оператору.
References: #2768
В диалект
mysql+gaerdbms
добавлено еще одно условие для определения так называемого «режима разработки», в котором следует использоватьrdbms_mysqldb
DBAPI. Исправление любезно предоставлено Бреттом Слаткиным.References: #2715
Аргумент ключевого слова
deferrable
наForeignKey
иForeignKeyConstraint
не будет приводить к появлению ключевого словаDEFERRABLE
на диалекте MySQL. В течение долгого времени мы оставляли это положение, поскольку не откладываемый внешний ключ будет вести себя совсем иначе, чем откладываемый, но некоторые среды просто отключают FK в MySQL, поэтому здесь мы будем менее категоричны.References: #2721
Обновлен диалект mysqlconnector для проверки отключения по видимому строковому сообщению, переданному в исключении; протестировано на mysqlconnector 1.0.9.
sqlite¶
В список имен типов, которые могут быть отражены диалектом SQLite, добавлено
sqlalchemy.types.BIGINT
; любезно предоставлено Расселом Стюартом.References: #2764
mssql¶
При запросе информационной схемы на SQL Server 2000 удален вызов CAST, который был добавлен в 0.8.1 для решения проблем с драйверами и, по всей видимости, не совместим с 2000. Для SQL Server 2005 и выше CAST остается на месте.
References: #2747
misc¶
В диалекты kinterbasdb и fdb добавлен новый флаг
retaining=True
. Он управляет значением флагаretaining
, передаваемого в методыcommit()
иrollback()
DBAPI-соединения. По историческим причинам в версии 0.8.2 этот флаг по умолчанию принимает значениеTrue
, однако в версии 0.9.0b1 он принимает значениеFalse
.References: #2763
Поиск типа при отражении типов Firebird LONG и INT64 исправлен таким образом, что LONG рассматривается как INTEGER, INT64 - как BIGINT, если только тип не имеет «точности», в этом случае он рассматривается как NUMERIC. Исправление любезно предоставлено Расселом Стюартом.
References: #2757
Исправлена ошибка, из-за которой, если составной тип задавался функцией, а не классом, расширение mutable сбивалось при попытке проверить столбец на принадлежность к
MutableComposite
(а это не так). Любезно предоставлено asldevi.Для работы набора модульных тестов теперь требуется библиотека Python mock. Хотя начиная с версии Python 3.3 она входит в состав стандартной библиотеки, для запуска модульных тестов или использования пакета
sqlalchemy.testing
для внешних диалектов потребуется установить ее и в предыдущих версиях Python.
0.8.1¶
Released: April 27, 2013orm¶
В Query добавлен удобный метод, превращающий запрос в подзапрос EXISTS вида
EXISTS (SELECT 1 FROM ... WHERE ...)
.References: #2673
Исправлена ошибка, когда запрос вида:
query(SubClass).options(subqueryload(Baseclass.attrname))
, гдеSubClass
является объединенным входомBaseClass
, не применялJOIN
внутри подзапроса на загрузку атрибутов, создающих картезианское произведение. При этом заполненные результаты, как правило, оставались корректными, поскольку дополнительные строки просто игнорировались, поэтому данная проблема может проявляться как снижение производительности в приложениях, которые в остальном работают корректно.This change is also backported to: 0.7.11
References: #2699
Исправлена ошибка в единице работы, при которой подкласс с объединенным наследованием мог вставить строку для «под» таблицы перед родительской таблицей, если между двумя таблицами не были установлены ограничения ForeignKey.
This change is also backported to: 0.7.11
References: #2689
Исправления в расширении
sqlalchemy.ext.serializer
, включая превращение передаваемого из pickler’а «id» в строку для предотвращения разбора байтов на Py3K, а также то, что конструкцииrelationship()
иorm.join()
теперь правильно сериализуются.References: #2698
Значительно улучшена работа query.join(), в результате чего процесс принятия решения о том, как присоединиться, значительно упростился. Появились новые тестовые примеры, например, множественные присоединения, расширяющиеся из середины уже сложной серии присоединений, включающих наследование и т.п. Объединение из глубоко вложенных структур подзапросов все еще остается сложным и не лишенным предостережений, но благодаря этим усовершенствованиям можно надеяться, что крайние случаи будут отодвинуты еще дальше на задний план.
References: #2714
В процесс распикировки объектов, отображенных в ORM, добавлено условие, согласно которому если при распикировке объекта ссылка на него была потеряна, то мы не будем ошибочно пытаться установить _sa_instance_state - исправлена ошибка NoneType.
Исправлена ошибка, при которой отношения «многие-ко-многим» с uselist=False не удаляли строку ассоциации и выдавали ошибку, если атрибут scalar был установлен в None. Это была регрессия, возникшая в результате изменений для #2229.
References: #2710
Улучшено поведение управления экземплярами в отношении создания сильных ссылок внутри сессии; у объекта больше не будет создаваться внутренний цикл ссылок, если он находится в переходном состоянии или переходит в отсоединенное состояние - сильная ссылка создается только при присоединении объекта к сессии и удаляется при отсоединении объекта. Это делает несколько более безопасным сопоставление объекту метода __del__() method, even though this is not recommended, as relationships with backrefs produce cycles too. A warning has been added when a class with a __del__().
References: #2708
Исправлена ошибка, из-за которой ORM выполняла неправильный запрос при обновлении класса, отображенного на наследование, когда суперкласс был отображен на объект, не являющийся таблицей, например, пользовательский join() или select(), выполняя запрос, предполагающий иерархию, отображенную на отдельные таблицы-первоклассы.
References: #2697
Исправлено __repr__() в конструкциях свойств mapper, чтобы они работали до инициализации объекта, так что сборки Sphinx с последними версиями Sphinx могут их читать.
orm declarative¶
Исправлена косвенная регрессия, связанная с
has_inherited_table()
, когда, поскольку он учитывал__table__
текущего класса, был чувствителен к времени его вызова. Такое поведение было и в 0.7, но в 0.7, как правило, «срабатывало» внутри событий типа__mapper_args__()
.has_inherited_table()
теперь учитывает только суперклассы, поэтому должен возвращать один и тот же ответ относительно текущего класса независимо от того, когда он был вызван (очевидно, предполагая состояние суперкласса).References: #2656
examples¶
Исправлена давняя ошибка в примере с кэшированием, когда значения параметров limit/offset не учитывались при вычислении ключа кэша. Функция _key_from_query() была упрощена и теперь работает непосредственно с итоговым скомпилированным запросом, получая как полный текст запроса, так и полностью обработанный список параметров.
sql¶
Ослаблена проверка имен аргументов, передаваемых в Table() в зависимости от диалекта; поскольку мы хотим поддерживать внешние диалекты, а также поддерживать аргументы без установленного диалекта, теперь проверяется только формат аргумента, а не поиск этого диалекта в sqlalchemy.dialects.
Полностью реализованы операторы IS и IS NOT для констант True/False. Теперь выражение типа
col.is_(True)
на целевой платформе будет отображаться какcol IS true
, а не преобразовывать константу True/False в целочисленный параметр. Это позволяет операторуis_()
работать в MySQL при задании констант True/False.References: #2682
Исправлен способ, которым объект select() выдает маркированные столбцы при использовании функции apply_labels(); в этом режиме создается SELECT, в котором каждый столбец маркирован как в <tablename>_<columnname>, чтобы устранить коллизии имен столбцов при выборе нескольких таблиц. Исправление заключается в том, что если две метки сталкиваются в сочетании с именем таблицы, например, «foo.bar_id» и «foo_bar.id», то к одному из дубликатов будет применено анонимное сглаживание. Это позволяет ORM обрабатывать оба столбца независимо друг от друга; ранее в 0.7 в некоторых случаях молча выдавался второй SELECT для «дублированного» столбца, а в 0.8 выдавалась ошибка двусмысленного столбца. Ключи», применяемые к коллекции .c. в select(), также будут дедуплицированы, так что предупреждение «столбец заменяется» больше не будет выдаваться для любого select() с указанием use_labels, хотя дублирующему ключу будет присвоена анонимная метка, что в целом не очень удобно.
References: #2702
Исправлена ошибка, при которой обнаружение разъединения при ошибке приводило к ошибке атрибута, если ошибка возникала после того, как объект Connection уже был закрыт.
References: #2691
Переработаны внутренние вызовы исключений, которые перед повторным вызовом вызывают функцию rollback(), чтобы трассировка стека сохранялась из sys.exc_info() перед входом в функцию отката. Это позволяет сохранить трассировку при использовании корутинных фреймворков, которые могут переключать контекст до возврата функции отката.
References: #2703
Базовый тип _Binary теперь преобразует значения через вызываемую функцию bytes() при работе на Python 3; в частности, psycopg2 2.5 с Python 3.3, похоже, теперь возвращает тип «memoryview», поэтому он преобразуется в байты перед возвратом.
Улучшения в обработке автоопределения соединений. Если происходит ошибка, не связанная с разъединением, но приводящая к ошибке отложенного разъединения в рамках обработки ошибок (это происходит в MySQL), то состояние разъединения будет обнаружено. Теперь соединение может быть закрыто, если оно находится в недействительном состоянии, то есть при следующем использовании оно получит сообщение «закрыто». Кроме того, функция «закрыть с результатом» будет работать даже в случае сбоя автоотката в процедуре обработки ошибок и независимо от того, является ли условие отсоединением или нет.
References: #2695
Исправлена ошибка, при которой DBAPI, возвращающий «0» для cursor.lastrowid, работал некорректно в сочетании с
ResultProxy.inserted_primary_key
.
postgresql¶
Расширена проверка «разъединения» с помощью psycopg2/libpq для проверки всех различных сообщений «разъединения» в рамках полной иерархии исключений. В частности, сообщение «неожиданное закрытие соединения» теперь встречается как минимум в трех различных типах исключений. Любезно предоставлено Eli Collins.
References: #2712
Операторы для типа PostgreSQL ARRAY поддерживают входные типы множеств, генераторов и т.д., даже если размерность не указана, безусловно превращая заданную итерабельность в коллекцию.
References: #2681
В имена типов postgresql добавлен отсутствующий тип HSTORE, чтобы тип мог быть отражен.
References: #2680
mysql¶
Исправления для поддержки последней версии cymysql DBAPI, любезно предоставленные Хаджиме Накагами (Hajime Nakagami).
Улучшена работа диалекта pymysql на Python 3, включая некоторые важные шаги декодирования/байт. Остаются проблемы с BLOB-типами из-за проблем с драйвером. Предоставлено Беном Трофаттером.
References: #2663
Обновлен regexp для корректного извлечения кода ошибки на google app engine v1.7.5 и новее. Предоставлено Дэном Рингом.
mssql¶
В рамках более длинной серии исправлений, необходимых для pyodbc+ mssql, в связанный параметр для имени таблицы и имени схемы во всех запросах к информационной схеме добавлен CAST to NVARCHAR(max), чтобы избежать проблемы сравнения NVARCHAR с NTEXT, которая, похоже, отвергается драйвером ODBC в некоторых случаях, таких как FreeTDS (только 0.91?) плюс передаваемые связанные параметры unicode. По-видимому, эта проблема характерна для таблиц информационной схемы SQL Server, и обходной путь безвреден для тех случаев, когда проблема вообще не существует.
References: #2355
В диалект pymssql добавлена поддержка дополнительных сообщений «disconnect». Предоставлено Джоном Андерсоном.
Исправлена ошибка Py3K, связанная с «бинарными» типами и pymssql. Предоставлено Марком Абрамовицем.
References: #2683
0.8.0¶
Released: March 9, 2013Примечание
В версии 0.8.0 появились некоторые новые изменения в поведении, отсутствующие в версии 0.8.0b2. В документе по миграции они представлены следующим образом:
orm¶
Добавлен значимый атрибут
QueryableAttribute.info
, который проксирует вниз к атрибуту.info
либо на объектеColumn
, если он непосредственно присутствует, либо наMapperProperty
в противном случае. Полное поведение документировано и обеспечено тестами для сохранения стабильности.References: #2675
Можно установить/изменить атрибут «каскад» у конструкции
relationship()
после того, как она уже была построена. Это не является шаблоном для обычного использования, но мы любим изменять эту настройку для демонстрации в учебных пособиях.Добавлена новая вспомогательная функция
was_deleted()
, возвращающая True, если данный объект был объектом операцииSession.delete()
.References: #2658
Расширена система API для проверки во время выполнения, чтобы можно было получить все дескрипторы Python, связанные с ORM или его расширениями. Это удовлетворяет распространенному запросу на возможность проверки всех дескрипторов
QueryableAttribute
в дополнение к таким типам расширений, какhybrid_property
иAssociationProxy
. См.Mapper.all_orm_descriptors
.Улучшена проверка на конфликт имен существующих backref при настройке маппера; теперь помимо текущего маппера будет проверяться наличие конфликтов имен в суперклассах и подклассах, поскольку эти конфликты так же сильно мешают работе. Это новое для 0.8, но см. ниже предупреждение, которое также будет срабатывать в 0.7.11.
References: #2674
Улучшено сообщение об ошибке, выдаваемое при обнаружении «петли обратной ссылки», т.е. когда событие атрибута вызывает двунаправленное присвоение между двумя другими атрибутами без конца. Такое состояние может возникнуть не только при присвоении объекта неправильного типа, но и при неправильной настройке атрибута на обратную ссылку в существующую пару обратных ссылок. Также в 0.7.11.
References: #2674
Предупреждение выдается при назначении MapperProperty, заменяющего существующее свойство, если эти свойства не являются обычными свойствами, основанными на столбцах. Замена свойств отношений редко (никогда?) является целью и обычно относится к неправильной конфигурации картографа. Также в 0.7.11.
References: #2674
Если обработчик события пытается выполнить SQL на сессии в рамках обработчика after_commit(), где не выполняется жизнеспособная транзакция, то выдается явное сообщение об ошибке.
References: #2662
Обнаружение изменения первичного ключа в процессе каскадного обновления естественного первичного ключа будет успешным, даже если ключ является составным и изменились только некоторые атрибуты.
References: #2665
Объект, удаленный из сессии, после фиксации транзакции будет полностью деассоциирован с этой сессией, то есть функция
object_session()
вернет None.References: #2658
Исправлена ошибка, при которой метод
Query.yield_per()
некорректно устанавливал опции выполнения, что нарушало последующее использование методаQuery.execution_options()
. Предоставлено Райаном Келли.References: #2661
Исправлено рассмотрение оператора
between()
, чтобы он корректно работал с новой системой отношений local/remote.References: #1768
рассмотрение отложенного объекта как «сироты» было изменено, чтобы более точно соответствовать поведению постоянных объектов, которое заключается в том, что объект исключается из
Session
, как только он отсоединяется от любого из своих родителей с поддержкой сиротства. Ранее отложенный объект удалялся только в том случае, если он был удален от всех своих родителей, имеющих статус orphan. КMapper
добавляется новый флагlegacy_is_orphan
, который восстанавливает унаследованное поведение.Подробное обсуждение этого изменения см. в примечании к изменению и примере по адресу Рассмотрение «сиротского» объекта стало более агрессивным.
References: #2655
Исправлен (скорее всего, никогда не используемый) метод коллекции «@collection.link», срабатывающий каждый раз, когда коллекция ассоциируется или деассоциируется с сопоставленным объектом - декоратор не был протестирован и не работал. Теперь метод декоратора называется
collection.linker()
, хотя имя «link» сохраняется для обратной совместимости. Любезно предоставлено Лукой Верштедтом.References: #2653
Внесены некоторые исправления в систему создания пользовательских инструментальных коллекций, в основном, использование декораторов @collection теперь будет учитывать __mro__ данного класса, применяя логику версии конкретного метода коллекции для младших классов. Ранее при подклассификации существующего инструментального класса, такого как
MappedCollection
, было невозможно предсказать, будут ли корректно разрешаться пользовательские методы.References: #2654
Исправлена потенциальная утечка памяти, которая могла произойти при создании произвольного количества объектов
sessionmaker
. Анонимный подкласс, созданный сеансовым диспетчером, при разыменовании не собирал мусор из-за оставшихся ссылок на уровне класса из пакета событий. Эта проблема также относится к любой пользовательской системе, использующей специальные подклассы совместно с диспетчером событий. Также в 0.7.10.References: #2650
Query.merge_result()
теперь может загружать строки из внешнего объединения, где сущность может бытьNone
, без возникновения ошибки. Также в 0.7.10.References: #2640
Исправления в «динамическом» загрузчике на
relationship()
, включая то, что обратные ссылки будут работать корректно даже при отключенной автопромывке, события истории будут более точными в сценариях, когда происходит многократное добавление/удаление одного и того же объекта.References: #2637
Недокументированная (и, надеюсь, не используемая) система создания пользовательских коллекций с помощью структуры данных
__instrumentation__
, связанной с коллекцией, была удалена, так как это была сложная и непроверенная возможность, которая к тому же была по сути избыточной по сравнению с подходом декораторов. Также были произведены другие внутренние упрощения модуля orm.collections.
examples¶
Исправлена регрессия в примере examples/dogpile_caching, связанная с изменением #2614.
sql¶
Добавлен новый аргумент для
Enum
и его базыSchemaType
inherit_schema
. При установке вTrue
тип будет устанавливать свой атрибутschema
в атрибутTable
, с которым он связан. Это происходит и во время операцииTable.tometadata()
; теперьSchemaType
копируется во всех случаях, когда происходитTable.tometadata()
, а еслиinherit_schema=True
, то тип примет новое имя схемы, переданное в метод. Наличиеschema
важно при работе с бэкендом PostgreSQL, так как тип приводит к появлению оператораCREATE TYPE
.References: #2657
Index
теперь поддерживает произвольные SQL-выражения и/или функции в дополнение к прямым столбцам. Общие модификаторы включают использованиеsomecolumn.desc()
для нисходящего индекса иfunc.lower(somecolumn)
для индекса, не учитывающего регистр, в зависимости от возможностей целевого бэкенда.References: #695
Поведение корреляции SELECT было улучшено таким образом, что методы
Select.correlate()
иSelect.correlate_except()
, а также их ORM-аналоги, по-прежнему сохраняют «автокорреляцию», при которой предложение FROM модифицируется только в том случае, если вывод будет легальным SQL; то есть предложение FROM остается нетронутым, если коррелированный SELECT не используется в контексте вложенного SELECT внутри предложения WHERE, columns или HAVING. В этих двух методах теперь задаются только условия для «автокорреляции» по умолчанию, а не абсолютные списки FROM.References: #2668
Исправлена ошибка, связанная с аннотациями столбцов, которая, в частности, могла повлиять на некоторые случаи использования новых функций аннотации
remote()
иlocal()
, когда аннотации могли быть потеряны при использовании столбца в последующем выражении.Оператор
ColumnOperators.in_()
теперь будет коэрцитировать значенияNone
вnull()
.References: #2496
Исправлена ошибка, при которой
Table.tometadata()
приводил к ошибке, еслиColumn
имел как внешний ключ, так и альтернативное имя «.key» для столбца. Также в 0.7.10.References: #2643
insert().returning() вызывает информативную ошибку CompileError при попытке компиляции на диалекте, не поддерживающем RETURNING.
References: #2629
Изменен символ «REQUIRED», используемый компилятором для определения связанных параметров INSERT/UPDATE, которые необходимо передать, чтобы его было легче определить при написании пользовательского кода обработки связывания.
References: #2648
schema¶
<<<Теперь
MetaData.create_all()
иMetaData.drop_all()
будут воспринимать пустой список как указание не создавать/удалять элементы, а не игнорировать коллекцию.References: #2664
postgresql¶
Добавлена поддержка традиционного для PostgreSQL синтаксиса функции SUBSTRING, которая при использовании обычного
func.substring()
отображается как «SUBSTRING(x FROM y FOR z)». Предоставлено Gunnlaugur Þór Briem.This change is also backported to: 0.7.11
References: #2676
Добавлены методы
Comparator.any()
иComparator.all()
, а также самостоятельные конструкции выражений. Большое спасибо Аудриусу Кажукаускасу за отличную работу.Исправлена ошибка в конструкции
array()
, при которой ее использование внутри конструкцииinsert()
приводило к ошибке, связанной с проблемой параметра в методеself_group()
.
mysql¶
Добавлен новый диалект для CyMySQL, любезно предоставленный Хаджиме Накагами (Hajime Nakagami).
Диалект GAE теперь принимает аргументы имени пользователя/пароля в URL, любезно предоставленные Оуэном Нельсоном.
Добавлен условный импорт в диалект
gaerdbms
, который пытается импортировать rdbms_apiproxy вместо rdbms_googleapi для работы на платформах dev и production. Также теперь учитывается атрибутinstance
. Любезно предоставлено Шоном Линчем. Также в 0.7.10.References: #2649
Диалект GAE не выдаст ошибку при совпадении None, если код ошибки не может быть извлечен из броска исключения; любезно предоставлено Owen Nelson.
mssql¶
Добавлены опции
mssql_include
иmssql_clustered
кIndex
, приводящие к появлению ключевых словINCLUDE
иCLUSTERED
соответственно. Предоставлено Дереком Харландом.DDL для столбцов IDENTITY теперь поддерживается для столбцов, не являющихся первичными ключами, путем создания конструкции
Sequence
для любого целочисленного столбца. Предоставлено Дереком Харландом.References: #2644
Добавлено py3K-условие вокруг ненужного вызова .decode() в информационной схеме mssql, исправлено отражение в Py3K. Также в 0.7.10.
References: #2638
Исправлена ошибка, из-за которой перестал работать параметр «collation» в символьных типах CHAR, NCHAR и т.д., поскольку «collation» теперь поддерживается базовыми строковыми типами. Типы TEXT, NCHAR, CHAR, VARCHAR в диалекте MSSQL теперь являются синонимами базовых типов.
oracle¶
Диалект cx_oracle больше не будет передавать имена параметров связывания через
encode()
, так как это недопустимо на Python 3 и мешало корректной работе операторов на Python 3. Теперь мы кодируем только в том случае, еслиsupports_unicode_binds
имеет значение False, что не является верным для cx_oracle, если используется хотя бы 5-я версия cx_oracle.
tests¶
Исправлен импорт «logging» в test_execute, который не работал на некоторых платформах linux. Также в 0.7.11.
References: #2669
0.8.0b2¶
Released: December 14, 2012orm¶
В класс
KeyedTuple
добавленыKeyedTuple._asdict()
иKeyedTuple._fields
для обеспечения некоторой совместимости со стандартной библиотекой Pythoncollections.namedtuple()
.References: #2601
Разрешить использование синонимов при определении первичных и вторичных связей для отношений.
Теперь метод
Query.select_from()
можно использовать с конструкциейaliased()
, не вмешиваясь в работу выбираемых сущностей. В принципе, заявление типа:ua = aliased(User) session.query(User.name).select_from(ua).join(User, User.name > ua.name)
При этом в предложении SELECT для столбцов будет указано, что они исходят от несглаженного «пользователя»; select_from имеет место только в предложении FROM:
SELECT users.name AS users_name FROM users AS users_1 JOIN users ON users.name < users_1.name
Обратите внимание, что такое поведение противоречит оригинальному, более старому варианту использования
Query.select_from()
, который заключается в повторном представлении отображаемой сущности в терминах другого выбираемого:session.query(User.name).select_from(user_table.select().where(user_table.c.id > 5))
В результате чего образуются:
SELECT anon_1.name AS anon_1_name FROM (SELECT users.id AS id, users.name AS name FROM users WHERE users.id > :id_1) AS anon_1
Именно «алиасинговое» поведение второго варианта использования мешало первому варианту. Теперь метод специально рассматривает SQL-выражение типа
select()
илиalias()
отдельно от сопоставленной сущности типа конструкцииaliased()
.References: #2635
Тип
MutableComposite
не позволял использовать методMutableBase.coerce()
, хотя код, казалось, указывал на это, так что теперь это работает, и добавлен краткий пример. Как побочный эффект, механика этого обработчика событий была изменена таким образом, что новые типыMutableComposite
больше не добавляют глобальные обработчики событий для каждого типа. Также в 0.7.10.References: #2624
Второй пересмотр механики псевдонимов/внутренних путей теперь позволяет двум подклассам иметь разные отношения с одним и тем же именем, поддерживаемые подзапросом или объединенной ускоренной загрузкой для обоих одновременно при использовании полной полиморфной загрузки.
References: #2614
Исправлена ошибка, при которой многоходовая подзапросная нагрузка внутри конкретной нагрузки with_polymorphic приводила к ошибке KeyError. Используется та же перестройка внутреннего пути, что и в #2614.
References: #2617
Исправлена ошибка, при которой query.update() выдавал ошибку, если объект, найденный с помощью стратегии синхронизации «fetch», не присутствовал локально. Предоставлено Скоттом Торборгом.
References: #2602
orm extensions¶
Расширение
sqlalchemy.ext.mutable
теперь включает в себя пример классаMutableDict
как часть расширения.
engine¶
Методы
Connection.connect()
иConnection.contextual_connect()
теперь возвращают «разветвленную» версию, так что методConnection.close()
может быть вызван на возвращенном соединении, не затрагивая исходное. Обеспечивает симметрию при использовании объектовEngine
иConnection
в качестве менеджеров контекста:with conn.connect() as c: # leaves the Connection open c.execute("...") with engine.connect() as c: # closes the Connection c.execute("...")
Исправлено
MetaData.reflect()
для корректного использования заданногоConnection
, если оно задано, без открытия второго соединения изEngine
этого соединения.This change is also backported to: 0.7.10
References: #2604
Аргумент «reflect=True» в методе
MetaData
устарел. Пожалуйста, используйте методMetaData.reflect()
.
sql¶
Конструкция
Insert
теперь поддерживает многозначные вставки, т.е. INSERT, имеющий вид «INSERT INTO table VALUES (…), (…), …». Поддерживаются PostgreSQL, SQLite и MySQL. Большая благодарность Идану Камаре за проделанную работу.References: #2623
Исправлена ошибка, при которой использование server_onupdate=<FetchedValue|DefaultClause> без передачи флага «for_update=True» приводило к применению объекта по умолчанию к server_default, уничтожая все, что там было. Явный аргумент for_update=True при таком использовании не нужен (тем более что в документации приведен пример без его использования), поэтому теперь, если флаг не установлен на то, что соответствует этому аргументу, он организуется внутренне, используя копию данного объекта по умолчанию.
This change is also backported to: 0.7.10
References: #2631
Исправлена регрессия, вызванная операцией #2410, когда при разборе SQL-выражения для родительской таблицы операция
CheckConstraint
возвращала себя к исходной таблице во время операцииTable.tometadata()
. Теперь операция копирует данное выражение, чтобы оно соответствовало новой таблице.References: #2633
Исправлена ошибка, при которой использование значения label_length для dialect, меньшего, чем размер реальных идентификаторов столбцов, приводило к некорректному отображению столбцов в операторе SELECT.
References: #2610
Тип
DECIMAL
теперь учитывает аргументы «точность» и «масштаб» при выводе DDL.References: #2618
Внесена корректировка в «булевую» (т.е.
__nonzero__
) оценку бинарных выражений (т.е.x1 == x2
), благодаря которой «автогруппировка», применяемаяBinaryExpression
в некоторых случаях, не будет мешать этому сравнению. Ранее выражение типа:expr1 = mycolumn > 2 bool(expr1 == expr1)
Оценивается как
False
, несмотря на то, что это сравнение идентичности, посколькуmycolumn > 2
будет «сгруппирован» перед помещением вBinaryExpression
, что изменит его идентичность.BinaryExpression
теперь отслеживает переданные «оригинальные» объекты. Кроме того, метод__nonzero__
теперь возвращает только оператор==
или!=
- все остальные возвращаютTypeError
.References: #2621
Исправлена ошибка, при которой случайный вызов list() на
ColumnElement
мог привести к бесконечному циклу, если был реализованColumnOperators.__getitem__()
. Новая ошибка NotImplementedError выдается через__iter__()
.Исправлена ошибка в функции type_coerce(), из-за которой информация о типе могла быть потеряна, если оператор использовался в качестве подзапроса внутри другого оператора, а также в других подобных ситуациях. Кроме всего прочего, это приводило к потере информации о типе, когда диалекты Oracle/mssql применяли обертку ограничения/смещения.
References: #2603
Исправлена ошибка, из-за которой «.key» колонки не использовался при создании «прокси» колонки для selectable. Вероятно, в 0.7 этого не происходило, поскольку 0.7 не использует «.key» в более широком спектре сценариев.
References: #2597
postgresql¶
sqlite¶
В 0.7.9 была выпущена дополнительная доработка, связанная с SQLite, для перехвата устаревших символов кавычек SQLite при отражении внешних ключей. Помимо перехвата двойных кавычек, теперь перехватываются и другие символы кавычек, такие как скобки, обратные знаки и одинарные кавычки.
This change is also backported to: 0.7.10
References: #2568
mssql¶
Добавлена поддержка отражения «имени» ограничений первичного ключа, любезно предоставленная Дэйвом Муром.
References: #2600
Исправлена ошибка, при которой использование «key» с Column в сочетании со «schema» для таблицы-владельца приводило к невозможности найти строки результата из-за того, что логика «рендеринга схемы» диалекта MSSQL не учитывала .key.
This change is also backported to: 0.7.10
oracle¶
Исправлено отражение таблиц в Oracle при обращении к синониму, ссылающемуся на удаленную базу данных DBLINK; хотя такой синтаксис присутствует в диалекте Oracle уже некоторое время, до сих пор он не был протестирован. Синтаксис был протестирован на примере базы данных, ссылающейся на саму себя, однако до сих пор существует некоторая неопределенность относительно того, что должно использоваться в качестве «владельца» при запросе информации о таблице в удаленной базе данных. В настоящее время для соответствия «владельцу» используется значение «username» из user_db_links.
References: #2619
Тип Oracle LONG, являясь неограниченным текстовым типом, не использует тип cx_Oracle.LOB при возврате строк результатов, поэтому диалект был исправлен, чтобы исключить применение к LONG фильтрации cx_Oracle.LOB. Также в 0.7.10.
References: #2620
Исправлено использование
.prepare()
в связке с cx_Oracle таким образом, что при возврате значенияFalse
вызовconnection.commit()
не производится, что позволяет избежать ошибок «нет транзакции». В настоящее время доказано, что двухфазные транзакции рудиментарно работают с SQLAlchemy и cx_oracle, однако это связано с оговорками, наблюдаемыми при работе с драйвером; подробности смотрите в документации. Также в 0.7.10.References: #2611
misc¶
В диалект Sybase добавлена поддержка Reflection. Большое спасибо Бену Трофаттеру (Ben Trofatter) за проделанную работу по разработке и тестированию.
References: #1753
Теперь
Pool
будет одинаково регистрировать все операции connection.close(), включая закрытие недействительных соединений, отсоединенных соединений и соединений, превышающих емкость пула.Теперь
Pool
обращается кDialect
за функциональностью относительно того, как следует «автоматически откатывать» соединение, а также закрывать его. Это дает диалекту больше контроля над областью транзакций, что позволит нам лучше реализовать транзакционные обходные пути, подобные тем, которые потенциально могут понадобиться для pysqlite и cx_oracle.References: #2611
Добавлен новый хук
PoolEvents.reset()
для перехвата события перед автооткатом соединения при возврате в пул. Вместе сConnectionEvents.rollback()
это позволяет перехватывать все события отката.Добавлен недостающий импорт для «fdb» в экспериментальный диалект «firebird+fdb».
References: #2622
Были удалены некоторые недостатки, связанные с обработкой транзакций в Informix, в том числе функция, позволяющая пропустить вызов commit()/rollback(), а также некоторые жестко заданные предположения об уровне изоляции при выполнении begin(). Состояние этого диалекта не совсем понятно, поскольку у нас нет ни пользователей, работающих с ним, ни доступа к базе данных Informix. Если кто-то, имеющий доступ к Informix, хочет помочь в тестировании этого диалекта, пожалуйста, сообщите нам об этом.
0.8.0b1¶
Released: October 30, 2012general¶
Синоним «sqlalchemy.exceptions» для «sqlalchemy.exc» полностью удален.
References: #2433
SQLAlchemy 0.8 теперь поддерживает Python 2.5 и выше. Python 2.4 больше не поддерживается.
orm¶
Значительная переработка внутренних функций relationship() теперь позволяет использовать условия присоединения, включающие столбцы, указывающие на себя в составных внешних ключах. Добавлен новый API для очень специализированных условий primaryjoin, позволяющий обрабатывать условия, основанные на SQL-функциях, CAST и т.д., помещая при необходимости в выражение аннотационные функции remote() и foreign() inline. Предыдущие рецепты, использующие получастный подход _local_remote_pairs, могут быть переведены на этот новый подход.
References: #1401
Новая самостоятельная функция with_polymorphic() предоставляет функциональность query.with_polymorphic() в самостоятельном виде. Она может быть применена к любой сущности в запросе, в том числе в качестве цели объединения вместо модификатора «of_type()».
References: #2333
Конструкция of_type() для атрибутов теперь принимает конструкции класса aliased(), а также конструкции with_polymorphic и работает с query.join(), any(), has(), а также с eager-загрузчиками subqueryload(), joinedload(), contains_eager().
Усовершенствования в прослушивании событий для сопоставленных классов позволяют указывать не сопоставленные классы для экземпляров и сопоставителей событий. Установленные события будут автоматически устанавливаться для подклассов этого класса при передаче флага propagate=True, а также события будут устанавливаться для самого класса, если и когда он будет отображен.
References: #2585
Система «отложенного декларативного отражения» была перенесена в само декларативное расширение с помощью нового класса DeferredReflection. Теперь этот класс протестирован как для одиночного, так и для объединенного наследования таблиц.
References: #2485
Добавлена новая функция ядра «inspect()», которая служит общим шлюзом для интроспекции отображателей, объектов и др. Объекты Mapper и InstanceState дополнены публичным API, позволяющим проверять отображаемые атрибуты, включая фильтры для свойств, связанных с колонками или отношениями, проверку текущего состояния объекта, историю атрибутов и т.д.
References: #2208
Вызов функции rollback() в рамках session.begin_nested() теперь приводит к истечению срока действия только тех объектов, которые имели чистые изменения в рамках данной транзакции, то есть объектов, которые были грязными или были модифицированы на флеше. Это позволяет в типичном случае использования begin_nested(), когда изменяется небольшое подмножество объектов, оставить на месте данные из большего охватывающего множества объектов, которые не были изменены в этой субтранзакции.
References: #2452
Добавлена служебная функция Session.enable_relationship_loading(), заменяющая relationship.load_on_pending. Однако следует избегать использования обеих функций.
References: #2372
Добавлена поддержка аргумента .info словаря для column_property(), relationship(), composite(). Все классы MapperProperty в целом имеют возможность автоматического создания .info dict.
Добавление/удаление None из сопоставленной коллекции теперь генерирует события атрибутов. Ранее добавление None в некоторых случаях игнорировалось. Связано с.
References: #2229
Наличие None в сопоставленной коллекции теперь вызывает ошибку при промывке. Ранее значения None в коллекциях молча игнорировались.
References: #2229
Метод Query.update() стал более гибким по отношению к обновляемой таблице. Теперь лучше поддерживаются простые объекты Table, и в update() можно использовать дополнительный подкласс с объединенным наследованием; таблица подкласса будет целью обновления, и если в предложении WHERE есть ссылка на родительскую таблицу, то компилятор вызовет синтаксис UPDATE..FROM, разрешенный диалектом, чтобы удовлетворить предложению WHERE. Также поддерживается возможность обновления нескольких таблиц MySQL, если столбцы указаны по объектам в словаре «values». Функция PG DELETE..USING также пока недоступна в Core.
Новые события сессии after_transaction_create и after_transaction_end позволяют отслеживать новые объекты SessionTransaction. Если объект проверяется, то с его помощью можно определить, когда сессия впервые становится активной и когда она деактивируется.
Теперь Query может загружать строки «кортежей», содержащие типы, которые не являются хэшируемыми, установив флаг «hashable=False» на соответствующем используемом объекте TypeEngine. Пользовательские типы, возвращающие нехешируемые типы (обычно списки), могут установить этот флаг в значение False.
References: #2592
Query теперь «автоматически коррелирует» по умолчанию так же, как и select(). Ранее для соотнесения внутренней и внешней таблицы Query, используемой в качестве подзапроса в другом запросе, требовался явный вызов метода correlate(). Как обычно, correlate(None) отключает корреляцию.
References: #2179
Событие after_attach теперь выдается после создания объекта в Session.new или Session.identity_map при Session.add(), Session.merge() и т.д., чтобы объект был представлен в этих коллекциях при вызове события. Добавлено событие before_attach для реализации сценариев, в которых требуется автопромывка предварительно подключенного объекта.
References: #2464
Сессия будет выдавать предупреждения, если внутри части «выполнить» флеша используются неподдерживаемые методы. Речь идет о привычных методах add(), delete() и т.д., а также о манипуляциях с коллекциями и связанными объектами, вызываемых в событиях flush на уровне маппера, таких как after_insert(), after_update() и т.д. О том, что SQLAlchemy не может гарантировать результат при манипуляциях с сессией в рамках выполнения плана flush, было сказано уже давно, однако пользователи продолжают это делать, поэтому теперь есть предупреждение. Возможно, когда-нибудь сессия будет усовершенствована для поддержки таких операций внутри flush, но пока результаты не могут быть гарантированы.
ORM-сущности могут быть переданы в основную конструкцию select(), а также в методы select_from(), correlate() и correlate_except() функции select(), где они будут развернуты в selectables.
References: #2245
Некоторая поддержка автоматического создания условия присоединения к отношениям на основе сопоставленного атрибута с использованием основных конструкций SQL. Например, select([SomeClass]).where(SomeClass.somerelationship) будет отображать SELECT from «someclass» и использовать primaryjoin «somerelationship» в качестве условия WHERE. Это меняет прежнее значение «SomeClass.somerelationship» при использовании в контексте основного SQL; ранее оно «разрешалось» в родительский selectable, что было не совсем удобно. Также работает с query.filter(). Связано с.
References: #2245
Реестр классов в declarative_base() теперь представляет собой WeakValueDictionary. Таким образом, разыменованные подклассы «Base» будут собраны в мусор, если на них не ссылаются никакие другие картографы/мапперы суперклассов. См. следующее примечание к этому билету.
References: #2526
Конфликты между колонками в декларативных подклассах с одним наследованием, с использованием или без использования миксина, могут быть разрешены с помощью нового использования @declared_attr, описанного в документации.
References: #2472
declared_attr теперь можно использовать и для классов, не являющихся миксинами, хотя это обычно полезно только для разрешения конфликта графов подклассов с одним наследованием.
References: #2472
Теперь declared_attr можно использовать с атрибутами, которые не являются Column или MapperProperty; включая любые значения, определяемые пользователем, а также прокси-объекты ассоциаций.
References: #2517
Очень ограниченная поддержка наследования отображателей для GC’ed при деференцировании самого класса. Картограф не должен иметь собственную таблицу (т.е. только одну таблицу inh) без полиморфных атрибутов. Это позволяет использовать случай создания временного подкласса декларативного сопоставленного класса, не имеющего собственных таблиц или директив сопоставления, для сбора мусора при обращении к нему в модульном тесте.
References: #2526
В Declarative теперь ведется реестр классов как по строковому имени, так и по полному имени, определяемому модулем. Поиск нескольких классов с одинаковыми именами теперь может осуществляться на основе строки, определяемой модулем, в функции relationship(). При простом поиске по имени класса, когда более одного класса имеют одинаковое имя, теперь выдается информативное сообщение об ошибке.
References: #2338
Теперь можно предоставлять атрибуты, привязанные к классу, которые переопределяют столбцы любого неORM-типа, а не только дескрипторы.
References: #2535
В Query.subquery() добавлены ключевые аргументы with_labels и reduce_columns, обеспечивающие две альтернативные стратегии создания запросов с уникальными именованными столбцами. …
References: #1729
Предупреждение выдается в том случае, если ссылка на инструментальную коллекцию больше не связана с родительским классом из-за истечения срока действия/обновления атрибутов/замены коллекции, но при этом получена операция append или remove для теперь уже отсоединенной коллекции.
References: #2476
ORM будет прилагать дополнительные усилия для определения того, что FK-зависимость между двумя таблицами не является существенной во время промывки, если таблицы связаны через объединенное наследование и FK-зависимость не является частью условия inherit_condition, избавляя пользователя от директивы use_alter.
References: #2527
События инструментария class_instrument(), class_uninstrument() и attribute_instrument() теперь будут срабатывать только для классов-потомков класса, назначенного на listen(). Ранее слушатель событий назначался на прослушивание всех классов во всех случаях, независимо от переданного аргумента «target».
References: #2590
with_polymorphic() создает JOIN-ы в правильном порядке и с правильными таблицами наследования в случае передачи многоуровневых подклассов в произвольном порядке или при отсутствии промежуточных классов.
References: #1900
Улучшения в работе с соединенными/подзапросами, работающими с цепочками сущностей подклассов, имеющих общую базу, при отсутствии определенной «глубины соединения». При обнаружении «цикла», вместо того, чтобы считать базовый класс источником «цикла», цепочка будет передаваться каждому отображателю подклассов в отдельности.
References: #2481
Флаг «passive» в Session.is_modified() больше не имеет никакого эффекта. is_modified() во всех случаях смотрит только на локальные флаги модификации в памяти и не будет выдавать SQL или вызывать callables/initializers загрузчика.
References: #2320
Предупреждение, выдаваемое при использовании каскада delete-orphan с one-to-many или many-to-many без single-parent=True, теперь является ошибкой. В любом случае после этого предупреждения ORM не будет функционировать.
References: #2405
Ленивые загрузки, выполняемые в событиях flush, таких как before_flush(), before_update() и т.д., теперь будут работать так же, как и в не-событийном коде, в части учета значений PK/FK, используемых в лениво выполняемом запросе. Ранее устанавливались специальные флаги, заставляющие ленивую загрузку загружать связанные элементы на основе «предыдущего» значения родительских PK/FK-значений именно при обращении к ним в рамках флеша; теперь сигнал к такой загрузке локализуется в том месте, где единица работы действительно должна загрузиться таким образом. Обратите внимание, что UOW иногда загружает эти коллекции до вызова события before_update(), поэтому использование «passive_updates» может повлиять на то, будет ли коллекция представлять «старые» или «новые» данные при обращении к ней в рамках события flush, в зависимости от того, когда была произведена ленивая загрузка. Данное изменение является обратно несовместимым в том случае, если пользовательский код событий зависит от старого поведения.
References: #2350
В продолжение вопроса о дополнительных состояниях после промывки, вызванных слушателями событий; все состояния, которые помечены как «грязные» с точки зрения атрибутов, обычно через события установки атрибутов столбцов в after_insert(), after_update() и т.д., получат сброшенный флаг «истории» во всех случаях, а не только в тех экземплярах, которые были частью промывки. Это приводит к тому, что «грязное» состояние не переносится после flush и не приводит к появлению UPDATE-операторов. При этом выдается предупреждение; метод set_committed_state() может быть использован для назначения атрибутов объектам без создания событий истории.
Исправлена нестыковка между столбцом @declared_attr и непосредственно определенным столбцом в миксине. В обоих случаях столбец будет применяться к таблице объявленного класса, но не к таблице подкласса с присоединенным наследованием. Ранее непосредственно определенный столбец помещался как в базовую, так и в подтаблицу, что обычно не является желаемым.
References: #2565
Теперь Declarative может распространять столбец, объявленный в подклассе, наследующем одну таблицу, до таблицы родительского класса, если родительский класс сам сопоставлен с оператором join() или select(), непосредственно или через объединенное наследование, а не просто с таблицей.
References: #2549
При сочетании uselist=False с «динамическим» загрузчиком выдается ошибка. Это предупреждение в версии 0.7.9.
Устаревшая «мутабельная» система ORM, включающая класс MutableType, а также флаг mutable=True в PickleType и postgresql.ARRAY, была удалена. Для обнаружения мутаций на месте ORM использует расширение sqlalchemy.ext.mutable, появившееся в версии 0.7. Удаление MutableType и связанных с ним конструкций значительно усложняет внутреннее устройство SQLAlchemy. Этот подход оказался неудачным, так как при его использовании приходилось сканировать все содержимое сессии.
References: #2442
Устранены устаревшие идентификаторы:
аргумент mapper() allow_null_pks (используйте allow_partial_pks)
Метод отображения _get_col_to_prop() (используйте get_property_by_column())
Аргумент dont_load для Session.merge() (используйте load=True)
Модуль sqlalchemy.orm.shard (используйте sqlalchemy.ext.horizontal_shard)
Интерфейс InstrumentationManager и вся связанная с ним система реализации альтернативных классов теперь вынесена в sqlalchemy.ext.instrumentation. Это редко используемая система, которая вносит значительную сложность и накладные расходы в механику инструментария классов. Новая архитектура позволяет ей оставаться неиспользуемой до тех пор, пока InstrumentationManager не будет импортирован, и тогда она будет загружена в ядро.
examples¶
Пример кэширования Beaker был переведен на использование dogpile.cache. Это новая библиотека кэширования, написанная тем же создателем внутренних компонентов кэширования Beaker, и представляет собой значительно улучшенную, упрощенную и модернизированную систему кэширования.
См.также
References: #2589
engine¶
Слушатели событий подключения теперь могут быть связаны с отдельными объектами Connection, а не только с объектами Engine.
References: #2511
Событие before_cursor_execute срабатывает для так называемых событий «_cursor_execute», которые обычно являются специальными случаями выполнения связанных последовательностей первичных ключей и SQL-фраз по умолчанию, которые вызываются отдельно, когда RETURNING не используется с INSERT.
References: #2459
Библиотеки, используемые набором тестов, были немного перемещены, чтобы они снова стали частью установки SQLAlchemy. Кроме того, новый набор тестов присутствует в новом пакете sqlalchemy.testing.suite. Это разрабатываемая система, которая надеется предоставить универсальный набор тестов для внешних диалектов. Диалекты, поддерживаемые вне SQLAlchemy, могут использовать новое тестовое приспособление в качестве основы для своих собственных тестов и получат бесплатно набор тестов, ориентированных на диалекты, включая улучшенную систему «требований», в которой определенные возможности и функции могут быть включены или отключены для тестирования.
Добавлена новая система регистрации новых диалектов в процессе работы без использования точки входа. См. документацию «Регистрация новых диалектов».
References: #2462
Флаг «required» по умолчанию устанавливается в True, если он не передан явно, в bindparam(), если не переданы параметры «value» или «callable». Это приведет к тому, что при выполнении оператора будет проверяться наличие параметра в конечной коллекции связанных параметров, а не будет неявно присваиваться None.
References: #2556
Различные доработки API «диалекта» для улучшения поддержки узкоспециализированных систем, таких как база данных Akiban, включая дополнительные крючки, позволяющие контексту выполнения обращаться к процессорам типов.
Inspector.get_primary_keys() устарел; используйте Inspector.get_pk_constraint(). Предоставлено Дианой Кларк.
References: #2422
Добавлен новый модуль расширения Си «utils» для дополнительного ускорения работы функций по мере появления времени на реализацию.
Функция Inspector.get_table_names() order_by=»foreign_key» теперь сортирует таблицы сначала по зависимому, чтобы соответствовать util.sort_tables и metadata.sorted_tables.
Исправлена ошибка, при которой, если перезапуск базы данных затрагивал несколько соединений, каждое соединение по отдельности вызывало новое удаление пула, хотя требовалось только одно удаление.
References: #2522
Имена столбцов в атрибуте .c. в select().apply_labels() теперь основываются на <tablename>_<colkey> вместо <tablename>_<colname>, для тех столбцов, которые имеют четкое имя .key.
References: #2397
Флаг autoload_replace для Table, если он равен False, приведет к тому, что все отраженные ограничения внешнего ключа, которые ссылаются на уже объявленные столбцы, будут пропущены, предполагая, что объявленный в Python столбец возьмет на себя задачу указания объявлений ForeignKey или ForeignKeyConstraint в Python.
Методы ResultProxy inserted_primary_key, last_updated_params(), last_inserted_params(), postfetch_cols(), prefetch_cols() утверждают, что данное утверждение является скомпилированной конструкцией и представляет собой утверждение insert() или update() в зависимости от ситуации, иначе возникает ошибка InvalidRequestError.
References: #2498
ResultProxy.last_inserted_ids удален, заменен на inserted_primary_key.
sql¶
В
Engine
добавлен новый методEngine.execution_options()
. Этот метод работает аналогичноConnection.execution_options()
, создавая копию родительского объекта, которая будет ссылаться на новый набор опций. Метод может быть использован для построения схем шардинга, когда каждый движок использует один и тот же базовый пул соединений. Метод был протестирован и на рецепте горизонтального шардинга в ORM.См.также
Значительная переработка системы операторов в Core, позволяющая переопределять существующие операторы, а также добавлять новые на уровне типов. На основе существующих типов можно создавать новые типы, которые добавляют или переопределяют операции, экспортируемые в выражения столбцов, подобно тому, как в ORM реализована функция comparator_factory. Новая архитектура переносит эту возможность в ядро, чтобы она была последовательно применима во всех случаях и распространялась с использованием существующего поведения распространения типов.
References: #2547
В дополнение к этому типы теперь могут предоставлять «выражения привязки» и «выражения столбца», которые позволяют вводить SQL-выражения в операторы на уровне столбца или привязки. Это позволяет использовать тип, которому необходимо дополнить поведение bind- и result- на уровне SQL, а не на уровне Python. Позволяет реализовать такие схемы, как прозрачное шифрование/дешифрование, использование функций PostGIS и т.д.
Система операторов Core теперь включает оператор getitem, т.е. оператор скобки в Python. Сначала он используется для обеспечения поведения индекса и среза для типа PostgreSQL ARRAY, а также предоставляет крючок для определения конечным пользователем пользовательских схем __getitem__, которые могут применяться как на уровне типов, так и в рамках пользовательских схем операторов на уровне ORM. В качестве дополнительных операторов также поддерживаются lshift (<<) и rshift (>>).
Обратите внимание, что в результате этого изменения схемы __getitem__, основанные на дескрипторах и используемые ORM в сочетании с synonym() или другими схемами, «обернутыми дескрипторами», должны будут начать использовать пользовательский компаратор, чтобы сохранить такое поведение.
Пересмотрены правила определения старшинства оператора, определяемого пользователем, т.е. оператора, предоставляемого с помощью метода
op()
. Ранее во всех случаях применялся наименьший приоритет, теперь по умолчанию используется нулевой приоритет, который ниже всех операторов, кроме «запятой» (например, используемой в списке аргументов вызоваfunc
) и «AS», а также настраивается с помощью аргумента «precedence» в методеop()
.References: #2537
Добавлен параметр «collation» для всех типов String. Если он присутствует, то отображается как COLLATE <collation>. Это сделано для поддержки ключевого слова COLLATE, которое теперь поддерживается некоторыми базами данных, включая MySQL, SQLite и PostgreSQL.
References: #2276
Пользовательские унарные операторы теперь можно использовать, комбинируя operators.custom_op() с UnaryExpression().
Улучшены GenericFunction и func.*, чтобы пользовательские подклассы GenericFunction были доступны через пространство имен func.* автоматически по имени класса, опционально с использованием имени пакета, а также с возможностью иметь имя, отличное от идентифицированного имени в func.*.
Конструкции cast() и extract() теперь будут производиться и через аксор func.*, поскольку пользователи, естественно, пытаются обращаться к этим именам из func.*, то они вполне могут сделать то, что ожидается, даже если возвращаемый объект не является FunctionElement.
References: #2562
Теперь объект Inspector может быть получен с помощью новой функции inspect(), входящей в состав
References: #2208
Событие column_reflect теперь принимает объект Inspector в качестве первого аргумента, предшествующего «table». Код, использующий версию 0.7 этого нового события, должен быть модифицирован для добавления объекта «inspector» в качестве первого аргумента.
References: #2418
Поведение нацеливания столбцов в наборах результатов теперь по умолчанию чувствительно к регистру. В течение многих лет SQLAlchemy выполняла преобразование этих значений без учета регистра, вероятно, для облегчения ранних проблем с чувствительностью к регистру в таких диалектах, как Oracle и Firebird. В более современных версиях эти проблемы были решены более чисто, так что проблема снижения производительности при вызове функции lower() для идентификаторов устранена. Нечувствительное к регистру сравнение может быть восстановлено установкой параметра «case_insensitive=False» в create_engine().
References: #2423
Предупреждение «неиспользованные имена столбцов», выдаваемое при наличии в insert.values() или update.values() ключей, отсутствующих в целевой таблице, теперь является исключением.
References: #2415
Добавлен пункт «MATCH» в ForeignKey, ForeignKeyConstraint, любезно предоставленный Райаном Келли.
References: #2502
Добавлена поддержка DELETE и UPDATE из псевдонима таблицы, который, как предполагается, будет связан с самим собой в другом месте запроса, любезно предоставленная Райаном Келли.
References: #2507
В функции select() имеется метод correlate_except(), который автоматически коррелирует все селекты, кроме переданных.
Метод prefix_with() теперь доступен для каждого из select(), insert(), update(), delete(), причем все они имеют один и тот же API, принимая несколько вызовов префикса, а также «имя диалекта», так что префикс может быть ограничен одним видом диалекта.
References: #2431
В конструкцию select() добавлен метод reduce_columns(), заменяющий столбцы в строке с помощью утилиты util.reduce_columns для удаления эквивалентных столбцов. В reduce_columns() также добавлен параметр «with_only_synonyms» для ограничения сокращения только теми столбцами, которые имеют одинаковые имена. Устаревшая функция fold_equivalents() удалена.
References: #1729
Переработаны операторы startswith(), endswith(), contains() для лучшей работы с отрицанием (NOT LIKE), а также для их сборки во время компиляции, чтобы можно было изменять отображаемый SQL, как, например, в случае с Firebird STARTING WITH
References: #2470
В систему рендеринга CREATE TABLE добавлен хук, предоставляющий доступ к рендерингу для каждого столбца в отдельности, путем построения функции @compiles относительно новой конструкции schema.CreateColumn.
References: #2463
»Скалярные» селекты теперь имеют метод WHERE для помощи в генеративном построении. Также немного изменен способ «соотнесения» столбцов в SS; новая методика больше не применяет значение к столбцу таблицы, из которой производится выборка. Это позволило улучшить некоторые достаточно эзотерические ситуации, а существовавшая логика, похоже, не имела никакого смысла.
При первом использовании ForeignKeyConstraint(), созданного для обращения к нескольким удаленным таблицам, возникает явная ошибка.
References: #2455
В
ColumnOperators
добавленыColumnOperators.notin_()
,ColumnOperators.notlike()
,ColumnOperators.notilike()
.References: #2580
Тип Text() отображает заданную ему длину, если она была указана.
Перед большинством классов в expression.sql больше не ставится знак подчеркивания, например, Label, SelectBase, Generative, CompareMixin. Класс _BindParamClause также переименован в BindParameter. Старые названия этих классов с подчеркиванием останутся доступными в качестве синонимов в обозримом будущем.
Исправлена ошибка, из-за которой аргументы ключевого слова, переданные в
Compiler.process()
, не распространялись на выражения столбцов, присутствующие в предложении columns оператора SELECT. В частности, это проявлялось при использовании пользовательских схем компиляции, которые полагались на специальные флаги.References: #2593
Функция автокорреляции
select()
и, соответственно,Query
не будет действовать для оператора SELECT, который выводится непосредственно в список FROM вложенного SELECT. Корреляция в SQL применяется только к выражениям столбцов, например, в выражениях WHERE, ORDER BY, columns.References: #2595
Изменен приоритет столбцов, в результате чего операторы «concat» и «match» стали такими же, как операторы «is», «like» и другие; это помогает при выводе скобок при использовании их в сочетании с «IS».
References: #2564
Применение выражения столбца в операторе select с использованием метки с другими модифицирующими конструкциями или без них больше не будет «нацеливать» это выражение на базовый столбец; это влияет на операции ORM, которые полагаются на нацеливание на столбец для получения результатов. То есть запрос типа query(User.id, User.id.label(„foo“)) теперь будет отслеживать значение каждого выражения «User.id» отдельно, а не объединять их вместе. Не ожидается, что это повлияет на пользователей; однако, если в запросе select() используется select() в сочетании с query.from_statement() и делается попытка загрузить полностью составленные сущности ORM, то они могут работать не так, как ожидалось, если в select() названы объекты Column с произвольными именами .label(), поскольку они больше не будут нацелены на объекты Column, сопоставленные с данной сущностью.
References: #2591
Исправления в интерпретации параметра Column «default» как вызываемого, чтобы не передавать ExecutionContext в параметр аргумента ключевого слова.
References: #2520
Все UniqueConstraint, ForeignKeyConstraint, CheckConstraint и PrimaryKeyConstraint автоматически привязываются к родительской таблице, если они ссылаются на объект Table-bound Column напрямую (т.е. не просто на строковое имя столбца), и ссылаются на одну и только одну таблицу. До версии 0.8 такое поведение было характерно для UniqueConstraint и PrimaryKeyConstraint, но не для ForeignKeyConstraint и CheckConstraint.
References: #2410
TypeDecorator теперь включает в себя общий метод repr(), который по умолчанию работает в терминах типа «impl». Это является изменением поведения для тех классов TypeDecorator, которые определяют собственный метод __init__; таким типам придется переопределить __repr__(), если им нужно, чтобы __repr__() обеспечивал достоверное представление конструктора.
References: #2594
Функция column.label(None) теперь выдает анонимную метку, а не возвращает сам объект колонки, что соответствует поведению функции label(column, None).
References: #2168
Убран давно устаревший и нефункциональный флаг
assert_unicode
наcreate_engine()
, а такжеString
.
postgresql¶
В postgresql.ARRAY появился необязательный аргумент «dimension», который позволяет назначить массиву определенное количество размерностей, которые в DDL будут выглядеть как ARRAY[][]…, также повышается производительность обработки привязки/результатов.
References: #2441
postgresql.ARRAY теперь поддерживает индексирование и нарезку. Оператор Python [] доступен для всех SQL-выражений, имеющих тип ARRAY; можно передавать целочисленные или простые фрагменты. Слайсы также можно использовать на стороне присваивания в предложении SET оператора UPDATE, передавая их в Update.values(); примеры см. в документации.
Добавлена новая конструкция «литерал массива» postgresql.array(). По сути, это «кортеж», который отображается как ARRAY[1,2,3].
Добавлена поддержка ключевого слова PostgreSQL ONLY, которое может появляться соответственно таблице в операторе SELECT, UPDATE или DELETE. Фраза устанавливается с помощью функции with_hint(). Предоставлено Райаном Келли
References: #2506
Словарь «ischema_names» диалекта PostgreSQL является «неофициально» настраиваемым. То есть в этот словарь могут быть добавлены новые типы, например, типы PostGIS, и код отражения типов PG должен уметь работать с простыми типами с переменным числом аргументов. Данная функциональность является «неофициальной» по трем причинам:
это не «официальный» API. В идеале «официальный» API должен позволять создавать пользовательские вызываемые элементы обработки типов на диалектном или глобальном уровне в общем виде.
Это реализовано только для диалекта PG, в частности, потому, что PG имеет более широкую поддержку пользовательских типов по сравнению с другими бэкендами баз данных. Настоящий API должен быть реализован на уровне диалекта по умолчанию.
Приведенный здесь код отражения протестирован только на простых типах и, вероятно, имеет проблемы с более композиционными типами.
патч любезно предоставлен Éric Lemoine.
mysql¶
В диалект mysql добавлен тип TIME, принимающий аргумент «fst», который является новым спецификатором «дробных секунд» для последних версий MySQL. Тип будет интерпретировать полученную от драйвера порцию микросекунд, однако следует иметь в виду, что в настоящее время большинство/всех DBAPI MySQL не поддерживают возврат этого значения.
References: #2534
Dialect больше не выдает дорогостоящий серверный запрос collations, а также серверный casing при первом подключении. Эти функции по-прежнему доступны как полуприватные.
References: #2404
sqlite¶
Типы даты и времени SQLite были переработаны для поддержки более открытого формата ввода и вывода, с использованием строк формата, основанных на именах, и регексов. Новый аргумент «microseconds» также предоставляет возможность опускать часть «microseconds» во временных метках. Спасибо Натану Райту за работу и тестирование.
References: #2363
В список распознаваемых имен типов для отражения в диалекте SQLite добавлены
NCHAR
,NVARCHAR
. SQLite возвращает имя, присвоенное типу, в качестве возвращаемого имени.References: rc3addcc9ffad
mssql¶
В диалекте SQL Server могут быть заданы имена схем с уточнением базы данных, например, «schema=“mydatabase.dbo“»; операции отражения определят это, разделят схему на «.», чтобы получить владельца отдельно, и выдадут оператор «USE mydatabase» перед отражением целей внутри владельца «dbo»; затем будет восстановлена существующая база данных, возвращенная из DB_NAME().
обновлена поддержка драйвера mxodbc; для полной совместимости рекомендуется использовать mxodbc 3.2.1.
удалено устаревшее поведение, при котором сравнение столбцов в скалярном SELECT через == приводило к IN в диалекте SQL-сервера. Это неявное поведение, которое не работает в других сценариях, поэтому оно удалено. Код, который полагается на это, должен быть модифицирован для явного использования column.in_(select).
References: #2277
oracle¶
Типы столбцов, исключаемых из набора setinputsizes(), можно настроить, передав список строковых имен типов DBAPI для исключения с помощью диалектного параметра exclude_setinputsizes. Ранее этот список был фиксированным. Также по умолчанию теперь используются STRING, UNICODE, а CLOB, NCLOB удалены из списка.
References: #2561
Информация о цитировании теперь передается из колонки с quote=True при генерации одноименного связанного параметра в объект bindparam(), как это происходит в генерируемых операторах INSERT и UPDATE, что позволяет полностью поддерживать неизвестные зарезервированные имена.
References: #2437
Конструкция CreateIndex в Oracle теперь будет проверять соответствие имени индекса схеме родительской таблицы. Ранее это имя опускалось, что, по-видимому, создавало индекс в схеме по умолчанию, а не в схеме таблицы.
misc¶
диалект MS Access был перенесен в собственный проект на Bitbucket, используя преимущества нового набора средств обеспечения соответствия диалектов SQLAlchemy. Диалект все еще находится в очень грубой форме и, вероятно, пока не готов к широкому использованию, однако сейчас он обладает очень грубой функциональностью. https://bitbucket.org/zzzeek/sqlalchemy-access
Оператор «startswith()» отображается как «STARTING WITH», «~startswith()» отображается как «NOT STARTING WITH», используя более эффективный оператор FB.
References: #2470
Добавлен экспериментальный диалект для драйвера fdb, но он не тестируется, так как я не могу добиться сборки пакета fdb.
References: #2504
При попытке выдать VARCHAR без длины, аналогично MySQL, возникает CompileError.
References: #2505
Firebird теперь использует строгие «правила связывания ansi», так что связанные параметры не отображаются в столбцах оператора - вместо этого они отображаются буквально.
Поддержка передачи datetime в виде даты при использовании типа DateTime в Firebird; другие диалекты поддерживают эту возможность.
Диалект MaxDB, который не функционирует уже несколько лет, перенесен в ожидающий своего завершения проект bitbucket, https://bitbucket.org/zzzeek/sqlalchemy-maxdb.