0.8 Changelog¶
0.8.7¶
Released: July 22, 2014orm¶
Исправлена ошибка в подзапросе eager loading, когда длинная цепочка eager loads через границу полиморфного подкласса в сочетании с полиморфной загрузкой не находила ссылку на подкласс в цепочке, выдавая ошибку с отсутствующим именем свойства на
AliasedClass
.References: #3055
Исправлена ошибка ORM, когда функция
class_mapper()
маскировала ошибки AttributeErrors или KeyErrors, которые должны были возникать во время конфигурации маппера из-за ошибок пользователя. Перехват ошибки атрибута/ключа был сделан более специфичным, чтобы не включать шаг конфигурации.References: #3047
sql¶
Исправлена ошибка в
Enum
и других подклассахSchemaType
, когда прямое связывание типа сMetaData
приводило к зависанию, когда наMetaData
испускались события (например, события создания).References: #3124
Исправлена ошибка в системе пользовательских операторов плюс
TypeEngine.with_variant()
, при которой использованиеTypeDecorator
в сочетании с variant приводило к ошибке MRO, когда использовался оператор сравнения.References: #3102
Исправлена ошибка в конструкции INSERT..FROM SELECT, когда выбор из объединения мог обернуть объединение в анонимный (например, немаркированный) подзапрос.
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 «команды рассинхронизированы» в современных версиях MySQL-Python возникает как ProgrammingError, а не OperationalError; все коды ошибок MySQL, которые проверяются на «is disconnect», теперь проверяются в OperationalError и ProgrammingError независимо друг от друга.
References: #3101
Исправлена ошибка, при которой имена столбцов, добавленные в параметр
mysql_length
в индексе, должны были иметь одинаковые кавычки для имен, взятых в кавычки, чтобы быть распознанными. Исправление делает кавычки необязательными, но также обеспечивает старое поведение для обратной совместимости с теми, кто использует обходной путь.References: #3085
Добавлена поддержка отражения таблиц, в которых индекс включает KEY_BLOCK_SIZE, используя знак равенства. Pull request любезно предоставлен Шоном МакГиверном.
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
Улучшено сообщение об ошибке, которая возникала, если запрос() выполнялся против невыбираемого объекта, такого как
literal_column()
, а затем была сделана попытка использоватьQuery.join()
таким образом, что «левая» сторона была бы определена какNone
и затем произошел бы сбой. Теперь это условие определяется явно.Удалены устаревшие имена из
sqlalchemy.orm.interfaces.__all__
и обновлены актуальными именами, так чтоimport *
из этого модуля снова работает.References: #2975
sql¶
Исправлена ошибка в конструкции
tuple_()
, когда «тип» по существу первого выражения SQL применялся в качестве «типа сравнения» к сравниваемому значению кортежа; в некоторых случаях это приводило к неправильному «принуждению типа», например, когда кортеж, содержащий смесь строковых и двоичных значений, неправильно принуждает целевые значения к двоичным, даже если они не являются таковыми с левой стороны.tuple_()
теперь ожидает неоднородные типы в своем списке значений.References: #2977
postgresql¶
Включена проверка «вменяемого подсчета нескольких строк» для psycopg2 DBAPI, так как это, похоже, поддерживается в psycopg2 2.0.9.
Исправлена регрессия, вызванная улучшением совместимости в релизах 0.8.5 / 0.9.3, когда отражение индексов в PostgreSQL версий, характерных только для серий 8.1, 8.2, снова выходило из строя, окружая всегда проблемный тип int2vector. В то время как int2vector поддерживает операции с массивами в версии 8.1, очевидно, что в версии 8.3 он поддерживает только CAST к varchar.
References: #3000
misc¶
Исправлена ошибка в mutable extension, а также
flag_modified()
, когда событие изменения не распространялось, если атрибут был переназначен на себя.References: #2997
0.8.5¶
Released: February 19, 2014orm¶
Исправлена ошибка, при которой
Query.get()
не мог последовательно поднятьInvalidRequestError
, вызываемый при вызове запроса с существующим критерием, когда заданный идентификатор уже присутствует в карте идентификаторов.References: #2951
Исправлено сообщение об ошибке, когда объект итератора передается в
class_mapper()
или подобное, где ошибка не выводилась при форматировании строки. Pullreq любезно предоставлен Кайлом Старком.Корректировка стратегии
subqueryload()
, которая обеспечивает выполнение запроса после начала процесса загрузки; это делается для того, чтобы загрузка подзапроса имела приоритет перед другими загрузчиками, которые могут попасть на тот же атрибут из-за других ситуаций с нетерпением/недозагрузкой в неподходящее время.References: #2887
Исправлена ошибка при использовании наследования объединенной таблицы из таблицы в select/alias на базе, где столбцы PK также имели разные имена; система персистентности не копировала значения первичного ключа из базовой таблицы в наследуемую таблицу при INSERT.
References: #2885
composite()
будет выдавать информативное сообщение об ошибке, когда переданные столбцы/атрибуты (имена) не разрешаются в столбец или сопоставленный атрибут (например, ошибочный кортеж); ранее выдавалось несвязанное локальное сообщение.References: #2889
engine¶
Исправлена критическая регрессия, вызванная #2880, когда новая одновременная возможность возвращать соединения из пула означает, что событие «first_connect» теперь также не синхронизируется, что приводит к неправильной конфигурации диалекта даже при минимальном параллелизме.
sql¶
Исправлена ошибка, при которой вызов
Insert.values()
с пустым списком или кортежем приводил к ошибке IndexError. Теперь он выдает пустую конструкцию вставки, как это было бы в случае с пустым словарем.References: #2944
Исправлена ошибка, при которой
ColumnOperators.in_()
переходил в бесконечный цикл, если ошибочно передавалось выражение столбца, компаратор которого включал метод__getitem__()
, например, столбец, использующий типARRAY
.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, где проверка на «charset соединения» была неудачной из-за более строгих правил сравнения значений в Py3K. В данном вызове в любом случае не учитывалась версия базы данных, так как версия сервера на тот момент была еще None, поэтому метод в целом был упрощен до использования connection.character_set_name().
References: #2933
В диалект cymysql добавлены некоторые недостающие методы, включая _get_server_version_info() и _detect_charset(). Pullreq любезно предоставлен Хаджиме Накагами.
sqlite¶
Восстановлено изменение, которое было упущено в бэкпорте отражения уникальных ограничений в 0.8, когда
UniqueConstraint
с SQLite выходило из строя, если в имена столбцов были включены зарезервированные ключевые слова. Pull request любезно предоставлен Романом Подолякой.
mssql¶
Флаг «asdecimal», используемый с типом
Float
, теперь будет работать с Firebird, а также с диалектами mssql+pyodbc; ранее десятичное преобразование не происходило.Добавлено сообщение «Net-Lib error during Connection reset by peer» в список сообщений, проверяемых на «disconnect» в диалекте pymssql. Предоставлено Джоном Андерсоном.
firebird¶
Диалект firebird будет заключать в кавычки идентификаторы, начинающиеся с подчеркивания. Любезно предоставлено Триве Джелбертом.
References: #2897
Исправлена ошибка в отражении индекса Firebird, когда столбцы внутри индекса не сортировались правильно; теперь они сортируются в порядке RDB$FIELD_POSITION.
misc¶
Исправлена ошибка Py3K, из-за отсутствия импорта которой режим «literal binary» не импортировал «util.binary_type» при визуализации связанного параметра. В 0.9 это решается по-другому. Pull request любезно предоставлен Андреасом Цайдлером.
Сообщение об ошибке при получении строкового аргумента
relationship()
, который не разрешается в класс или маппер, было исправлено, чтобы работать так же, как при получении нестрокового аргумента, который указывает имя отношения, в котором произошла конфигурационная ошибка.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-коде, если внутри
StatementError
поднимался пре-DBAPIConnection.execute()
, вызывая ошибки кодирования для не-ASCII-запросов. Теперь строфикация остается в рамках юникода Python, что позволяет избежать ошибок кодирования.References: #2871
sql¶
Добавлена поддержка отражения «уникального ограничения» с помощью метода
Inspector.get_unique_constraints()
. Спасибо Роману Подоляке за патч.References: #1443
postgresql¶
Исправлена ошибка, при которой отражение индекса неправильно интерпретировало значения indkey при использовании адаптера pypostgresql, который возвращает эти значения в виде списков, а psycopg2 возвращает тип строки.
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
Исправлена ошибка, при которой использование аннотации типа
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()
предназначен для снижения накладных расходов БД/сети, а не обязательно количества вызовов функций); теперь накладные расходы на вызовы функций меньше, чем при загрузке данных из столбца во всех случаях. Также уменьшилось количество объектов «lazy callable», создаваемых при загрузке, с 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» в таблицу истории, созданную в примере версионирования, поскольку эта таблица в любом случае не должна иметь autoinc, любезно предоставлено Патриком Шмидом.
engine¶
repr()
дляURL
отEngine
теперь будет скрывать пароль с помощью звездочек. Предоставлено Gunnlaugur Þór Briem.References: #2821
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")
Исправлена ошибка, при которой
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, чтобы гарантировать, что любые буквальные значения SQL-выражений отображаются непосредственно как литералы, а не как связанные параметры, в операторе CREATE INDEX. Это также изменяет схему рендеринга для других DDL, таких как ограничения.
References: #2742
select()
, который ссылается на самого себя в предложении FROM, обычно с помощью мутации на месте, будет выдавать информативное сообщение об ошибке, а не вызывать переполнение рекурсии.References: #2815
Нерабочий аргумент «schema» в
ForeignKey
устарел; выдает предупреждение. Удалено в 0.9.References: #2831
Исправлена ошибка, при которой использование события
column_reflect
для изменения.key
входящегоColumn
приводило к тому, что ограничения первичного ключа, индексы и ограничения внешнего ключа не отражались корректно.References: #2811
Оператор
ColumnOperators.notin_()
, добавленный в 0.8, теперь правильно выдает отрицание выражения «IN» при использовании против пустой коллекции.Исправлена ошибка, когда система выражений полагалась на форму
str()
некоторых выражений при обращении к коллекции.c
в конструкцииselect()
, но формаstr()
недоступна, поскольку элемент полагается на специфические для диалекта конструкции компиляции, в частности оператор__getitem__()
, используемый с элементом PostgreSQLARRAY
. Исправление также добавляет новый класс исключенийUnsupportedCompilationError
, который возникает в тех случаях, когда компилятору предлагается скомпилировать то, чего он не умеет.References: #2780
postgresql¶
Удалено 128-символьное усечение из отражения серверного значения по умолчанию для колонки; этот код был оригинальным из системных представлений PG, которые усекали строку для удобочитаемости.
References: #2844
Родительская скобка будет применяться к составному выражению SQL, как показано в списке столбцов оператора CREATE INDEX.
References: #2742
Исправлена ошибка, при которой строки версий PostgreSQL, содержащие префикс перед словами «PostgreSQL» или «EnterpriseDB», не обрабатывались. Предоставлено Скоттом Шефером.
References: #2819
mysql¶
Изменение в #2721, которое заключается в том, что ключевое слово
deferrable
вForeignKeyConstraint
молча игнорируется бэкендом MySQL, будет отменено в 0.9; теперь это ключевое слово будет отображаться снова, вызывая ошибки MySQL, поскольку оно не понимается - такое же поведение будет применяться и к ключевому словуinitially
. В 0.8 ключевые слова будут по-прежнему игнорироваться, но будет выдаваться предупреждение. Кроме того, ключевое словоmatch
теперь вызывает ошибкуCompileError
в 0.9 и предупреждение в 0.8; это ключевое слово не только молча игнорируется MySQL, но и нарушает опции ON UPDATE/ON DELETE.Чтобы использовать
ForeignKeyConstraint
, который не отображается или отображается по-другому на MySQL, используйте пользовательскую опцию компиляции. Пример такого использования был добавлен в документацию, смотрите mysql_foreign_keys.Диалект MySQL-connector теперь позволяет опциям в строке запроса create_engine переопределять значения по умолчанию, установленные в connect, включая «buffered» и «raise_on_warnings».
References: #2515
sqlite¶
Недавно добавленные в SQLite DATETIME аргументы storage_format и regexp, очевидно, были реализованы не полностью корректно; хотя аргументы принимались, на практике они не имели никакого эффекта; это было исправлено.
References: #2781
oracle¶
Исправлена ошибка, при которой отражение таблиц Oracle с использованием синонимов не выполнялось, если синоним и таблица находились в разных удаленных схемах. Патч для исправления предоставлен Кайлом Дерром.
References: #2853
misc¶
Добавлен новый флаг
system=True
кColumn
, который отмечает столбец как «системный» столбец, автоматически предоставляемый базой данных (например, 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, когда функция contextmanager
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
Удален вызов «not implemented»
__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
или подобную приставку, так как это мешало работе с такими типами, как дататаймы с учетом временных зон, но также, похоже, совсем не нужно в современных версиях 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¶
Добавлено
sqlalchemy.types.BIGINT
в список имен типов, которые могут быть отражены диалектом SQLite; любезно предоставлено Расселом Стюартом.References: #2764
mssql¶
При запросе информационной схемы на SQL Server 2000 удален вызов CAST, который был добавлен в версии 0.8.1 для решения проблем с драйверами, и который, очевидно, не совместим с 2000. CAST остается на месте для SQL Server 2005 и выше.
References: #2747
firebird¶
Добавлен новый флаг
retaining=True
в диалекты kinterbasdb и fdb. Он управляет значением флагаretaining
, передаваемого в методыcommit()
иrollback()
соединения DBAPI. По историческим причинам в 0.8.2 этот флаг по умолчанию имеет значениеTrue
, однако в 0.9.0b1 этот флаг по умолчанию имеет значениеFalse
.References: #2763
Поиск типа при отражении типов Firebird LONG и INT64 был исправлен таким образом, что LONG рассматривается как INTEGER, INT64 - как BIGINT, если тип не имеет «точности», в этом случае он рассматривается как NUMERIC. Исправление любезно предоставлено Расселом Стюартом.
References: #2757
misc¶
Исправлена ошибка, из-за которой, если составной тип задавался функцией вместо класса, расширение mutable сбивалось при попытке проверить столбец на принадлежность к
MutableComposite
(что не так). Любезно предоставлено asldevi.Для запуска набора модульных тестов теперь требуется библиотека Python mock. Хотя начиная с Python 3.3 она является частью стандартной библиотеки, предыдущие версии Python должны быть установлены для запуска модульных тестов или для использования пакета
sqlalchemy.testing
для внешних диалектов.
0.8.1¶
Released: April 27, 2013orm¶
В Query добавлен удобный метод, который превращает запрос в подзапрос EXISTS вида
EXISTS (SELECT 1 FROM ... WHERE ...)
.References: #2673
Исправления в расширении
sqlalchemy.ext.serializer
, включая то, что «id», передаваемый из pickler, превращается в строку для предотвращения разбора байтов на Py3K, а также то, что конструкцииrelationship()
иorm.join()
теперь правильно сериализуются.References: #2698
Значительно улучшена внутренняя работа query.join(), так что процесс принятия решения о том, как присоединиться, значительно упростился. Появились новые тестовые случаи, например, множественные соединения, выходящие из середины уже сложной серии соединений с наследованием и т.п. Объединение из глубоко вложенных структур подзапросов все еще остается сложным и не лишенным предостережений, но благодаря этим улучшениям, мы надеемся, что крайние случаи будут отодвинуты еще дальше на задний план.
References: #2714
Добавлено условие в процесс распикировки для ORM mapped объектов, так что если ссылка на объект была потеряна, когда объект был распикирован, мы не будем ошибочно пытаться установить _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
Переработаны внутренние исключения, которые вызывают откат() перед повторным вызовом, так что трассировка стека сохраняется из 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¶
Открыл проверку «disconnect» в psycopg2/libpq для проверки всех различных сообщений «disconnect» в полной иерархии исключений. В частности, сообщение «неожиданно закрыто соединение» теперь встречается как минимум в трех различных типах исключений. Любезно предоставлено Эли Коллинзом.
References: #2712
Операторы для типа PostgreSQL ARRAY поддерживают входные типы множеств, генераторов и т.д., даже если размерность не указана, безоговорочно превращая заданную итерабельность в коллекцию.
References: #2681
Добавлен отсутствующий тип HSTORE в имена типов postgresql, чтобы тип мог быть отражен.
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
Можно установить/изменить атрибут «cascade» для конструкции
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. Новый флагlegacy_is_orphan
добавлен кmapper()
, который восстанавливает прежнее поведение.Подробное обсуждение этого изменения см. в примечании к изменению и примере по адресу Рассмотрение «ожидающего рассмотрения» объекта как «сироты» стало более агрессивным.
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¶
Добавлены методы
Comparator.any()
иComparator.all()
, а также отдельные конструкции выражений. Большое спасибо Аудриусу Кажукаускасу за потрясающую работу.Исправлена ошибка в конструкции
array()
, из-за которой ее использование внутри конструкцииinsert()
приводило к ошибке, связанной с проблемой параметра в методеself_group()
.
mysql¶
Добавлен новый диалект для CyMySQL, любезно предоставленный Хаджиме Накагами.
Диалект GAE теперь принимает аргументы имени пользователя/пароля в URL, любезно предоставленные Оуэном Нельсоном.
Добавлен условный импорт в диалект
gaerdbms
, который пытается импортировать rdbms_apiproxy против rdbms_googleapi для работы на платформах dev и production. Также теперь учитывается атрибутinstance
. Любезно предоставлено Шоном Линчем. Также в 0.7.10.References: #2649
Диалект GAE не выдаст ошибку при совпадении None, если код ошибки не может быть извлечен из броска исключения; любезно предоставлено Оуэном Нельсоном.
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, что не так, если используется хотя бы версия 5 cx_oracle.
tests¶
Исправлен импорт «logging» в test_execute, который не работал на некоторых платформах linux. Также в 0.7.11.
References: #2669
0.8.0b2¶
Released: December 14, 2012orm¶
Добавлены
KeyedTuple._asdict()
иKeyedTuple._fields
к классуKeyedTuple
для обеспечения некоторой степени совместимости со стандартной библиотекой Pythoncollections.namedtuple()
.References: #2601
Разрешить использование синонимов при определении первичных и вторичных соединений для отношений.
Расширение
sqlalchemy.ext.mutable
теперь включает в себя пример классаMutableDict
как часть расширения.Метод
Query.select_from()
теперь можно использовать с конструкциейaliased()
без вмешательства в выбираемые сущности. В принципе, утверждение, подобное этому:ua = aliased(User) session.query(User.name).select_from(ua).join(User, User.name > ua.name)
Будет сохранять пункт columns в SELECT как исходящий от несглаженного «user», как указано; 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
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, в результате которой операция
CheckConstraint
возвращала себя к исходной таблице во время операцииTable.tometadata()
, поскольку она разбирала SQL-выражение для родительской таблицы. Теперь операция копирует данное выражение, чтобы оно соответствовало новой таблице.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» колонки не использовался при создании «прокси» колонки для селекта. Вероятно, в 0.7 этого не происходило, поскольку в 0.7 «.key» не используется в более широком диапазоне сценариев.
References: #2597
postgresql¶
HSTORE
теперь доступен в диалекте PostgreSQL. Также будут использоваться расширения psycopg2, если они доступны. Предоставлено Аудриусом Кажукаускасом.References: #2606
sqlite¶
Дополнительная корректировка этой проблемы, связанной с SQLite, которая была выпущена в 0.7.9, для перехвата устаревших символов цитирования 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 используется для соответствия «owner».
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
firebird¶
Добавлен недостающий импорт для «fdb» в экспериментальный диалект «firebird+fdb».
References: #2622
misc¶
В диалект Sybase добавлена поддержка отражения. Большое спасибо Бену Трофаттеру за всю работу по разработке и тестированию.
References: #1753
Pool
теперь будет одинаково регистрировать все операции connection.close(), включая закрытия, которые происходят для недействительных соединений, отсоединенных соединений и соединений, превышающих емкость пула.Теперь
Pool
обращается кDialect
за функциональностью относительно того, как соединение должно быть «автоматически свернуто», а также закрыто. Это дает диалекту больше контроля над областью транзакций, так что мы сможем лучше реализовать транзакционные обходные пути, подобные тем, которые потенциально необходимы для pysqlite и cx_oracle.References: #2611
Добавлен новый хук
PoolEvents.reset()
для перехвата события перед автооткатом соединения при возврате в пул. Вместе сConnectionEvents.rollback()
это позволяет перехватывать все события отката.Были удалены некоторые недостатки, касающиеся обработки транзакций в 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() в строке выражения, когда это необходимо. Предыдущие рецепты, использующие получастный подход _local_remote_pairs, могут быть обновлены до этого нового подхода.
References: #1401
Новая самостоятельная функция with_polymorphic() предоставляет функциональность query.with_polymorphic() в самостоятельном виде. Она может быть применена к любой сущности в запросе, в том числе в качестве цели объединения вместо модификатора «of_type()».
References: #2333
Конструкция of_type() для атрибутов теперь принимает конструкции класса aliased(), а также конструкции with_polymorphic, и работает с query.join(), any(), has(), а также с eager loaders 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 dictionary в 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. Если объект проверен, его можно использовать для определения того, когда сессия впервые становится активной и когда она деактивируется.
Запрос теперь может загружать строки «кортежей», содержащие типы, которые не являются хэшируемыми, путем установки флага «hashable=False» для соответствующего используемого объекта TypeEngine. Пользовательские типы, которые возвращают нехешируемые типы (обычно списки), могут установить этот флаг на False.
References: #2592
Query теперь «автоматически коррелирует» по умолчанию так же, как и select(). Раньше для того, чтобы соотнести таблицу, находящуюся внутри, с таблицей, находящейся снаружи, необходимо было явно вызывать метод correlate(), используемый в качестве подзапроса в другом запросе. Как всегда, correlate(None) отключает корреляцию.
References: #2179
Событие after_attach теперь испускается после создания объекта в Session.new или Session.identity_map при Session.add(), Session.merge() и т.д., чтобы объект был представлен в этих коллекциях при вызове события. Добавлено событие before_attach, чтобы приспособиться к случаям использования, когда требуется autoflush w предварительно прикрепленного объекта.
References: #2464
Session будет выдавать предупреждения, если внутри части flush «execute» используются неподдерживаемые методы. Это знакомые всем методы add(), delete() и т.д., а также манипуляции с коллекциями и связанными объектами, вызываемые в событиях flush на уровне маппера, таких как after_insert(), after_update() и т.д. Уже давно было задокументировано, что SQLAlchemy не может гарантировать результат при манипулировании сессией в рамках выполнения плана flush, однако пользователи все еще делают это, поэтому теперь есть предупреждение. Возможно, когда-нибудь Session будет усовершенствован для поддержки таких операций внутри 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
Добавлены ключевые аргументы with_labels и reduce_columns в Query.subquery(), чтобы обеспечить две альтернативные стратегии для создания запросов с уникально названными столбцами. …
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 cascade с 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
Продолжение относительно дополнительного состояния после flush из-за слушателей событий; любые состояния, которые помечены как «грязные» с точки зрения атрибутов, обычно через события установки атрибутов колонок в after_insert(), after_update() и т.д., получат флаг «history», сброшенный во всех случаях, а не только в тех, которые были частью flush. Это приводит к тому, что это «грязное» состояние не переносится после флеша и не приводит к появлению UPDATE-запросов. При этом выдается предупреждение; метод set_committed_state() можно использовать для назначения атрибутов объектам без создания событий истории.
Исправлена нестыковка, которая медленно развивалась между @declared_attr Column и непосредственно определенным Column в миксине. В обоих случаях колонка будет применяться к таблице объявленного класса, но не к таблице подкласса, связанного наследованием. Ранее прямо определенный столбец помещался как в базовую, так и в подтаблицу, что обычно не является желаемым.
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
Устранены устаревшие идентификаторы:
аргумент allow_null_pks mapper() (используйте 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¶
Слушатели событий подключения теперь могут быть связаны с отдельными объектами подключения, а не только с объектами 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 «dialect» для лучшей поддержки узкоспециализированных систем, таких как база данных Akiban, включая больше крючков, позволяющих контексту выполнения обращаться к процессорам типов.
Inspector.get_primary_keys() устарел; используйте Inspector.get_pk_constraint(). Предоставлено Дианой Кларк.
References: #2422
Новый модуль расширения C «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.execution_options()
вEngine
. Этот метод работает аналогичноConnection.execution_options()
в том смысле, что он создает копию родительского объекта, которая будет ссылаться на новый набор опций. Метод может быть использован для построения схем шардинга, в которых каждый механизм использует один и тот же базовый пул соединений. Метод также был протестирован против рецепта горизонтального шардинга в ORM.См.также
Engine.execution_options()
Значительная переработка системы операторов в 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» ко всем типам строк. Когда он присутствует, отображается как COLLATE <collation>. Это сделано для поддержки ключевого слова COLLATE, которое теперь поддерживается несколькими базами данных, включая MySQL, SQLite и PostgreSQL.
References: #2276
Пользовательские унарные операторы теперь можно использовать, комбинируя operators.custom_op() с UnaryExpression().
Улучшены GenericFunction и func.*, чтобы пользовательские подклассы GenericFunction были доступны через пространство имен func.* автоматически по имени класса, опционально с использованием имени пакета, а также с возможностью иметь отображаемое имя, отличное от идентифицированного имени в func.*.
Конструкции cast() и extract() теперь также будут производиться через аксессор func.*, поскольку пользователи, естественно, пытаются получить доступ к этим именам из func.*, они могут сделать то, что ожидается, даже если возвращаемый объект не является FunctionElement.
References: #2562
Объект инспектора теперь можно получить с помощью новой функции inspect(), входящей в состав
References: #2208
Событие column_reflect теперь принимает объект Inspector в качестве первого аргумента, предшествующего «table». Код, использующий версию 0.7 этого нового события, необходимо модифицировать, чтобы добавить объект «inspector» в качестве первого аргумента.
References: #2418
Поведение нацеливания столбцов в наборах результатов теперь по умолчанию чувствительно к регистру. В течение многих лет SQLAlchemy выполнял преобразование этих значений без учета регистра, вероятно, для облегчения проблем с чувствительностью к регистру в ранних диалектах, таких как Oracle и Firebird. В более современных версиях эти проблемы были решены более чисто, так что падение производительности при вызове функции lower() для идентификаторов устранено. Сравнение без учета регистра может быть повторно включено путем установки «case_insensitive=False» в create_engine().
References: #2423
Предупреждение «unconsumed column names», выдаваемое при наличии ключей в insert.values() или update.values(), которых нет в целевой таблице, теперь является исключением.
References: #2415
Добавлен пункт «MATCH» к ForeignKey, ForeignKeyConstraint, любезно предоставленный Райаном Келли.
References: #2502
Добавлена поддержка DELETE и UPDATE из псевдонима таблицы, который, предположительно, будет связан с самим собой в другом месте запроса, любезно предоставленная Райаном Келли.
References: #2507
select() имеет метод correlate_except(), который автоматически коррелирует все selectables, кроме переданных.
Метод 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.notin_()
,ColumnOperators.notlike()
,ColumnOperators.notilike()
кColumnOperators
.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() в сочетании с 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[][][]…, также улучшает производительность обработки bind/результатов.
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 должен быть реализован на уровне диалекта по умолчанию.
Код отражения здесь протестирован только для простых типов и, вероятно, имеет проблемы с более композиционными типами.
патч любезно предоставлен Эриком Лемуаном.
mysql¶
Добавлен тип TIME в диалект mysql, принимающий аргумент «fst», который является новым спецификатором «дробных секунд» для последних версий MySQL. Тип данных будет интерпретировать порцию микросекунд, полученную от драйвера, однако обратите внимание, что в настоящее время большинство/все MySQL DBAPI не поддерживают возврат этого значения.
References: #2534
Dialect больше не выдает дорогостоящий запрос серверных колаций, а также серверный кейсинг, при первом подключении. Эти функции по-прежнему доступны как полуприватные.
References: #2404
sqlite¶
типы даты и времени SQLite были переработаны для поддержки более открытого формата ввода и вывода, с использованием форматных строк на основе имен и регексов. Новый аргумент «микросекунды» также предоставляет возможность опускать часть «микросекунды» в метках времени. Спасибо Натану Райту за работу и тесты.
References: #2363
Добавлены
NCHAR
,NVARCHAR
в список распознаваемых имен типов диалекта SQLite для отражения. 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 теперь будет проверять соответствие имени индекса схеме родительской таблицы. Ранее это имя было опущено, что, очевидно, создавало индекс в схеме по умолчанию, а не в схеме таблицы.
firebird¶
Оператор «startswith()» отображается как «STARTING WITH», «~startswith()» отображается как «NOT STARTING WITH», используя более эффективный оператор FB.
References: #2470
Добавлен экспериментальный диалект для драйвера fdb, но он не проверен, так как я не могу заставить пакет fdb собраться.
References: #2504
Возникает CompileError при попытке выдать VARCHAR без длины, аналогично MySQL.
References: #2505
Firebird теперь использует строгие «правила связывания ansi», поэтому связанные параметры не отображаются в столбцах оператора - вместо этого они отображаются буквально.
Поддержка передачи datetime как даты при использовании типа DateTime в Firebird; другие диалекты поддерживают это.
misc¶
диалект MS Access был перенесен в свой собственный проект на Bitbucket, используя преимущества нового пакета соответствия диалекта SQLAlchemy. Диалект все еще находится в очень грубой форме и, вероятно, еще не готов для общего использования, однако теперь у него есть очень грубая функциональность. https://bitbucket.org/zzzeek/sqlalchemy-access.
Диалект MaxDB, который не функционирует уже несколько лет, перенесен в ожидающий своего завершения проект bitbucket, https://bitbucket.org/zzzeek/sqlalchemy-maxdb.