0.4 Changelog¶
0.4.8¶
Released: Sun Oct 12 2008orm¶
Исправлена ошибка, при которой условие inherit_condition передавалось в виде «A=B», а не «B=A», что приводило к ошибкам
References: #1039
Изменения, внесенные в новые, грязные и удаленные коллекции в SessionExtension.before_flush(), вступят в силу для этого флеша.
В InstrumentedAttribute добавлен метод label() для обеспечения форвардной совместимости с 0.5.
sql¶
column.in_(someselect) теперь можно использовать как выражение в столбцах, не пропуская подзапрос в предложение FROM
References: #1074
mysql¶
Добавлен тип MSMediumInteger.
References: #1146
sqlite¶
Добавлена пользовательская функция strftime(), которая обрабатывает даты до 1900 года.
References: #968
В диалекте sqlite отключена логика convert_unicode в String (и Unicode, UnicodeText и т.д.), чтобы соответствовать новому требованию pysqlite 2.5.0, согласно которому принимаются только юникодные объекты Python; https://itsystementwicklung.de/pipermail/list-pysqlite/2008-March/000018.html
oracle¶
0.4.7p1¶
Released: Thu Jul 31 2008orm¶
В методы scoped_session добавлены функции «add()» и «add_all()». Решение для версии 0.4.7:
from sqlalchemy.orm.scoping import ScopedSession, instrument setattr(ScopedSession, "add", instrument("add")) setattr(ScopedSession, "add_all", instrument("add_all"))
Исправлено несовместимое с версией 2.3 использование выражения set() и генератора в relation().
0.4.7¶
Released: Sat Jul 26 2008orm¶
Оператор contains() при использовании с many-to-many будет псевдонимом() вторичной (ассоциативной) таблицы, так что несколько вызовов contains() не будут конфликтовать друг с другом
References: #1058
Исправлена ошибка, препятствующая работе функции merge() в сочетании с функцией comparable_property()
параметр enable_typechecks=False в relation() теперь позволяет использовать только те подтипы, которые наследуют мапперы. Полностью несвязанные типы или подтипы, не настроенные на наследование отображения по отношению к целевому отображению, по-прежнему не допускаются.
Добавлен флаг is_active для сессий, позволяющий определять, когда транзакция находится в процессе выполнения. Этот флаг всегда равен True для «транзакционной» (в версии 0.5 - не «автокоммитной») сессии.
References: #976
sql¶
Исправлена ошибка при вызове select([literal(„foo“)]) или select([bindparam(„foo“)]).
schema¶
create_all(), drop_all(), create(), drop() - все они выдают ошибку, если имя таблицы или схемы содержит больше символов, чем задано в диалекте. Некоторые СУБД могут обрабатывать слишком длинные имена таблиц в процессе использования, и SQLA также может это делать. Однако различные сценарии отражения/проверки при создании не работают, поскольку мы ищем имя в таблицах каталога БД.
References: #571
Имя индекса, генерируемое при указании «index=True» для столбца, усекается до длины, соответствующей диалекту. Кроме того, индекс со слишком длинным именем не может быть явно удален с помощью функции Index.drop(), аналогично.
mysql¶
В список ключевых слов SQL, возвращающих строки результатов, добавлено „CALL“.
oracle¶
Oracle get_default_schema_name() «нормализует» имя перед возвратом, то есть возвращает имя в нижнем регистре, когда идентификатор определяется как нечувствительный к регистру.
при создании/удалении таблиц имя схемы учитывается при поиске существующей таблицы, чтобы таблицы в других пространствах имен владельцев с таким же именем не конфликтовали
References: #709
Теперь по умолчанию для курсоров устанавливается значение «arraysize», равное 50, которое настраивается с помощью аргумента «arraysize» в create_engine() в диалекте Oracle. Это сделано для того, чтобы учесть значение cx_oracle по умолчанию, равное «1», которое приводит к тому, что в Oracle отправляется много обращений. На самом деле это хорошо работает в сочетании с курсорами, связанными с BLOB/CLOB, которых может быть любое количество, но только на время выполнения запроса строки (поэтому BufferedColumnRow все еще необходим, но уже в меньшей степени).
References: #1062
- sqlite
добавить тип SLFloat, который соответствует сродству типа SQLite REAL. Ранее предоставлялся только тип SLNumeric, который удовлетворял сродству NUMERIC, но это не то же самое, что REAL.
misc¶
Исправлены курсоры server_side_cursors для корректного определения клаузул text().
Добавлен тип PGCidr.
References: #1092
0.4.6¶
Released: Sat May 10 2008orm¶
Исправление недавнего рефакторинга relation(), устраняющего экзотические отношения viewonly, которые соединяют локальную и удаленную таблицу несколько раз, при этом общий столбец разделяется между соединениями.
Также восстановлены конфигурации viewonly relation(), объединяющие несколько таблиц.
Добавлен экспериментальный флаг relation(), помогающий при первичном соединении функций и т.д., _local_remote_pairs=[tuples]. Это дополняет сложное условие primaryjoin, позволяющее указать отдельные пары столбцов, составляющие локальную и удаленную стороны отношения. Также улучшена генерация SQL с ленивой загрузкой для обработки размещения параметров связывания внутри функций и других выражений. (частичный прогресс в этом направлении)
References: #610
исправлено наследование одной таблицы таким образом, чтобы можно было без проблем наследовать одну таблицу от мэппера, наследующего объединенную таблицу.
References: #1036
Исправлена ошибка «concatenate tuple», которая могла возникнуть при использовании Query.order_by(), если имела место адаптация клаузул.
References: #1027
Убрано старое утверждение о том, что для отображаемых селектов требуются «имена псевдонимов» - теперь отображатель создает свой псевдоним, если таковой отсутствует. Правда, в этом случае в качестве источника атрибутов столбцов нужно использовать класс, а не отображаемый selectable - поэтому предупреждение все равно выдается.
исправления к функции «exists», связанные с наследованием (any(), has(), ~contains()); для отношений, связывающих с подклассами, в предложение EXISTS будет выводиться полный целевой join.
восстановлено использование метода расширения append_result() для первичных строк запроса, когда расширение присутствует, а возвращается результат только по одной сущности.
Также восстановлены конфигурации viewonly relation(), объединяющие несколько таблиц.
удалено старое утверждение о том, что для отображаемых селектов требуются «имена псевдонимов» - теперь отображатель создает свой псевдоним, если такового нет. Правда, в этом случае в качестве источника атрибутов столбцов нужно использовать класс, а не отображаемый selectable - поэтому предупреждение все равно выдается.
Доработана функция mapper._save_obj(), которая неоправданно вызывала __ne__() для скалярных значений при промывке
References: #1015
добавлена возможность ускоренной загрузки, при которой подзапросы, заданные как column_property() с явными именами меток (что, впрочем, не обязательно), будут иметь анонимизированную метку, когда экземпляр является частью eager join, чтобы избежать конфликтов с одноименным подзапросом или колонкой в родительском объекте.
References: #1019
Коллекции на основе множеств |=, -=, ^= и &= более строги к своим операндам и оперируют только с множествами, морозными множествами или подклассами типа коллекции. Ранее они могли принимать любое множество типа duck.
добавлен пример dynamic_dict/dynamic_dict.py, иллюстрирующий простой способ размещения поведения словаря поверх dynamic_loader.
sql¶
Добавлена поддержка COLLATE через оператор выражения .collate(<collation>) и sql-функцию collate(<expr>, <collation>).
Исправлена ошибка с union() при применении к операторам select, не связанным с таблицами
Улучшено поведение выражений text() при использовании их в качестве предложений FROM, например select().select_from(text(«sometext»))
References: #1014
Column.copy() учитывает значение «autoincrement», исправлено использование в Migrate
References: #1021
mssql¶
В параметры движка / dburi добавлен параметр «odbc_autotranslate». Любая заданная строка будет передана в строку соединения ODBC в виде:
»AutoTranslate=%s» % odbc_autotranslate
References: #1005
В параметры движка / dburi добавлен параметр «odbc_options». Указанная строка просто добавляется к строке odbc-соединения, сгенерированной SQLAlchemy.
Это должно избавить от необходимости добавлять огромное количество опций ODBC в будущем.
misc¶
В связках наследования таблиц используется несколько смягченная функция для создания «условия наследования» родительской таблицы, чтобы другие внешние ключи к еще не объявленным объектам Table не вызывали ошибку.
Исправлена ошибка компиляции реентерабельного маппера при использовании объявленного атрибута в ForeignKey, т.е. ForeignKey(MyOtherClass.someattribute)
Слушатели пула теперь могут быть предоставлены в виде словаря вызываемых элементов или (возможно, частично) утиного типа PoolListener - на ваш выбор.
добавлена опция «rollback_returned» для Pool, которая отключает откат(), выполняемый при возврате соединений. Этот флаг безопасно использовать только с базой данных, не поддерживающей транзакции (например, MySQL/MyISAM).
Ассоциативные прокси на основе множеств |=, -=, ^= и &= более строги к своим операндам и работают только с множествами, фростенсетами или другими ассоциативными прокси. Ранее они могли принимать любое множество с утиным типом.
Обработка встроенного модуля «SUBSTRING(:string FROM :start FOR :length)».
0.4.5¶
Released: Fri Apr 04 2008orm¶
Небольшое изменение в поведении session.merge() - проверка существующих объектов производится по атрибутам первичного ключа, а не обязательно _instance_key. Таким образом, реализована широко востребованная возможность:
x = MyObject(id=1) x = sess.merge(x)
фактически загрузит MyObject с id #1 из базы данных, если он там присутствует. merge() все равно копирует состояние данного объекта в постоянный, поэтому в примере, подобном приведенному выше, все атрибуты объекта «x» будут иметь значение «None», которое будет скопировано в постоянную копию. Их можно вернуть с помощью session.expire(x).
Также исправлено поведение функции merge(), при котором элементы коллекции, присутствующие в целевой, но не в объединенной коллекции, не удалялись из целевой.
Добавлена более агрессивная проверка на наличие «некомпилированных картографов», что особенно помогает при работе с декларативным слоем
References: #995
Методология, лежащая в основе «primaryjoin»/»secondaryjoin», была рефакторизована. Поведение должно быть немного более интеллектуальным, в первую очередь это касается сообщений об ошибках, которые были сокращены, чтобы быть более читаемыми. В небольшом количестве сценариев он может лучше разрешать правильный внешний ключ, чем раньше.
Добавлена функция comparable_property(), добавляющая поведение компаратора запросов к обычным, неуправляемым свойствам Python
функциональность query.with_polymorphic() была добавлена в mapper() в качестве конфигурационной опции.
- Она задается через несколько форм:
with_polymorphic=“*“ with_polymorphic=[mappers] with_polymorphic=(„*“, selectable) with_polymorphic=([mappers], selectable)
Этот параметр определяет стратегию полиморфной загрузки по умолчанию для унаследованных отображений. Если selectable не задан, то внешние соединения создаются для всех запрошенных картографов, наследующих объединенные таблицы. Обратите внимание, что автоматическое создание соединений несовместимо с наследованием конкретных таблиц.
Существующий флаг select_table в функции mapper() теперь устарел и является синонимом функции with_polymorphic(„*“, select_table). Обратите внимание, что «внутренности» select_table были полностью удалены и заменены новым, более гибким подходом.
Новый подход также автоматически позволяет работать с нетерпеливыми загрузками для подклассов, если они присутствуют, например:
sess.query(Company).options(eagerload_all())
для загрузки объектов Company, их сотрудников и коллекции „machines“ сотрудников, которые оказались инженерами. Также в ближайшее время должна быть введена опция запроса «with_polymorphic», которая позволит управлять функцией with_polymorphic() для отношений в каждом запросе.
добавил в Query две «экспериментальные» функции, «экспериментальные» в том смысле, что их конкретные названия/поведение еще не высечены на камне: _values() и _from_self(). Мы хотели бы получить отзывы о них.
В _values(*columns) передается список выражений столбцов, и возвращается новый запрос, который возвращает только эти столбцы. При вычислении возвращаемое значение представляет собой список кортежей, как и при использовании add_column() или add_entity(), с той лишь разницей, что «нулевая сущность», т.е. сопоставленный класс, не включается в результаты. Это означает, что наконец-то имеет смысл использовать в Query функции group_by() и having(), которые до сих пор лежали без дела.
В будущем этот метод может быть изменен таким образом, что его способность объединять, фильтровать и позволять другие опции, не связанные с «набором результатов», будет удалена, поэтому мы хотим узнать, как люди хотят использовать _values()… т.е. в самом конце, или же они предпочитают продолжать генерацию после его вызова.
_from_self() компилирует оператор SELECT для Query (за вычетом любых загрузчиков) и возвращает новый Query, который выбирает из этого SELECT. Таким образом, можно делать запросы из Query без необходимости извлекать оператор SELECT вручную. Это придает смысл операциям типа query[3:5]._from_self().filter(some criterion). Здесь нет особых противоречий, кроме того, что вы можете быстро создавать сильно вложенные запросы, которые менее эффективны, и мы хотим получить отзывы о выборе именования.
query.order_by() и query.group_by() будут принимать несколько аргументов с помощью *args (как это уже делает select()).
В Query добавлены некоторые удобные дескрипторы: query.statement возвращает полную конструкцию SELECT, query.whereclause - только часть WHERE конструкции SELECT.
Исправлен/прикрыт случай использования значения False/0 в качестве полиморфного дискриминатора.
Исправлена ошибка, из-за которой атрибуты synonym() не могли использоваться с наследованием
Исправлено усечение в SQL-функции символов подчеркивания в конце строки
References: #996
При истечении срока действия атрибутов на отложенном экземпляре ошибка не будет возникать при выполнении действия «refresh» и отсутствии результата.
Session.execute теперь может находить привязки по метаданным
Скорректировано определение понятия «самореферентный», которым должны быть любые два картографа с общим родителем (это влияет на то, требуется ли aliased=True при объединении с помощью Query).
Исправлен аргумент «from_joinpoint» в query.join() таким образом, что если предыдущее соединение было aliased, а это не aliased, то соединение все равно происходит успешно.
- Различные исправления «каскадного удаления»:
Исправлена операция «каскадного удаления» динамических отношений, которая в 0.4.2 была реализована только для поведения обнуления иностранных ключей, а не для реального каскадного удаления
Каскад удаления без каскада delete-orphan при схеме «многие-к-одному» не удаляет сирот, которые были отключены от родителя до вызова session.delete() на родителе (при схеме «один-ко-многим» это уже было).
Каскадное удаление с delete-orphan удаляет сироту независимо от того, остается ли он привязанным к своему также удаленному родителю или нет.
Каскад delete-orphan корректно определяется для отношений, присутствующих в суперклассах при использовании наследования.
References: #895
Исправлено вычисление order_by в Query для правильного псевдонима mapper-config’s order_by при использовании select_from()
Рефакторинг логики замены одной коллекции на другую в collections.bulk_replace, полезный для тех, кто создает многоуровневые коллекции.
Алгоритм каскадного обхода преобразован из рекурсивного в итерационный для поддержки глубоких объектных графов.
sql¶
таблицы с квалификацией схемы теперь будут помещать имя схемы впереди имени вкладки во всех выражениях для столбцов, а также при генерации меток столбцов. Это позволяет избежать коллизий имен схем во всех случаях
References: #999
теперь может разрешать селекты, которые коррелируют со всеми пунктами FROM и не имеют самого FROM. Обычно они используются в скалярном контексте, т.е. SELECT x, (SELECT x WHERE y) FROM table. Требуется явный вызов функции correlate().
“name“ больше не является обязательным аргументом конструктора Column(). Теперь он (как и .key) может быть отложен до момента добавления колонки в таблицу.
like(), ilike(), contains(), startswith(), endswith() принимают необязательный аргумент в виде ключевого слова «escape=<somestring>», который устанавливается в качестве управляющего символа с помощью синтаксиса «x LIKE y ESCAPE „<somestring>“».
random() теперь является общей sql-функцией и будет компилироваться в реализацию random базы данных, если таковая имеется.
update().values() и insert().values() принимают аргументы в виде ключевых слов.
Исправлена ошибка в select(), связанная с генерацией предложений FROM, в редких случаях могли быть созданы два предложения, когда одно из них должно было отменить другое. Этот симптом мог наблюдаться в некоторых ORM-запросах с большим количеством ускоренных загрузок.
Функция case() теперь также принимает словарь в качестве параметра whens. По умолчанию она также интерпретирует выражения «THEN» как значения, то есть case([(x==y, «foo»)]) будет интерпретировать «foo» как связанное значение, а не как выражение SQL. Для буквальных выражений SQL в этом случае используйте text(expr). Для самого критерия это могут быть буквальные строки только при наличии ключевого слова «value», в противном случае SA заставит явно использовать либо text(), либо literal().
mysql¶
Ключи connection.info, используемые диалектом для кэширования настроек сервера, изменились и теперь располагаются по именам.
mssql¶
Отраженные таблицы теперь будут автоматически загружать другие таблицы, на которые ссылаются внешние ключи в автозагружаемой таблице.
References: #979
Добавлена проверка executemany для пропуска выборки идентификаторов.
References: #916
Добавлены заглушки для небольшого типа даты.
References: #884
Добавлен новый ключевой параметр „driver“ для диалекта pyodbc. Подставляется в строку ODBC-соединения, если она задана, по умолчанию - „SQL Server“.
Добавлен новый параметр ключевого слова „max_identifier_length“ для диалекта pyodbc.
Улучшения в pyodbc + Unix. Если вы не смогли заставить эту комбинацию работать, пожалуйста, попробуйте еще раз.
oracle¶
Ключевое слово «owner» для объекта Table теперь устарело и является точным синонимом ключевого слова «schema». Теперь таблицы могут отражаться с альтернативными атрибутами «owner», явно указанными на объекте Table или не использующими «schema».
Вся «магия» поиска синонимов, DBLINK и т.д. при отражении таблицы по умолчанию отключена, если только вы не укажете в объекте Table значение «oracle_resolve_synonyms=True». Разрешение синонимов неизбежно приводит к беспорядочным догадкам, которые мы предпочли бы отключить по умолчанию. Когда флаг установлен, таблицы и связанные с ними таблицы будут разрешаться по синонимам во всех случаях, то есть если для конкретной таблицы существует синоним, то при отражении связанных таблиц будет использоваться именно он. Это более сложное поведение, чем раньше, поэтому по умолчанию он выключен.
misc¶
Функция «synonym» теперь может использоваться непосредственно с «declarative». Передайте декорированное свойство с помощью ключевого аргумента «дескриптор», например: somekey = synonym(„_somekey“, descriptor=property(g, s))
Функция «deferred» может использоваться вместе с «declarative». Самое простое использование - объявить deferred и Column вместе, например: data = deferred(Column(Text))
В Declarative также появились @synonym_for(…) и @comparable_using(…) - интерфейсы для синонима и comparable_property.
Улучшена компиляция мапперов при использовании декларативного метода; уже скомпилированные мапперы по-прежнему будут вызывать компиляцию других нескомпилированных мапперов при их использовании
References: #995
Declarative завершает настройку столбцов, не имеющих имен, и позволяет использовать более простой синтаксис.
- class Foo(Base):
__tablename__ = „foos“ id = Column(Integer, primary_key=True)
Наследование в декларативном режиме может быть отключено при передаче «inherits=None» в __mapper_args__.
declarative_base() принимает необязательный kwarg «mapper», который представляет собой любую вызываемую переменную/класс/метод, создающий mapper, например, declarative_base(mapper=scopedsession.mapper). Это свойство также может быть установлено для отдельных декларативных классов с помощью свойства «__mapper_cls__».
Привели в порядок курсоры на стороне сервера PG, добавили исправленные юнит-тесты в набор тестов по умолчанию. Улучшена уникальность идентификатора курсора
References: #1001
0.4.4¶
Released: Wed Mar 12 2008orm¶
any(), has(), contains(), ~contains(), уровень атрибутов == и != теперь корректно работают с самореферентными отношениями - клаузула внутри EXISTS алиасируется на «удаленной» стороне, чтобы отличить ее от родительской таблицы. Это относится как к однотабличным самореферентным отношениям, так и к самореферентным отношениям, основанным на наследовании.
Исправлено поведение операторов == и != на уровне relation() при сравнении с NULL для отношений «один-к-одному
References: #985
Исправлена ошибка, из-за которой атрибуты session.expire() не загружались для полиморфно отображенного экземпляра, сопоставленного с помощью маппера select_table.
Добавлена функция query.with_polymorphic() - задает список классов, происходящих от базового класса, который будет добавлен в предложение FROM запроса. Позволяет использовать подклассы в критерии filter(), а также нетерпеливо загружать атрибуты этих подклассов.
Ваши крики были услышаны: удаление отложенного элемента из атрибута или коллекции с помощью delete-orphan приводит к удалению элемента из сессии; при этом не возникает ошибки FlushError. Обратите внимание, что если вы явно сохранили элемент в session.save()“ed, то удаление атрибута/коллекции все равно выведет его из сессии.
session.refresh() и session.expire() приводят к ошибке при вызове экземпляров, которые не являются постоянными в рамках сессии
Исправлена потенциальная ошибка генерации, когда один и тот же запрос использовался для генерации нескольких объектов Query с помощью функции join().
Исправлена ошибка, появившаяся в версии 0.4.3, из-за которой при загрузке уже персистентного экземпляра, сопоставленного с наследованием по объединенной таблице, при использовании полиморфной_выборки по умолчанию «select» происходила бесполезная «вторичная» загрузка из объединенной таблицы. Это происходило из-за того, что при первой загрузке атрибуты помечались как просроченные и не снимались с них при предыдущей «вторичной» загрузке. Теперь атрибуты становятся непросроченными на основании их присутствия в __dict__ после успешного выполнения любой операции загрузки или фиксации.
Утратили силу методы запросов apply_sum(), apply_max(), apply_min(), apply_avg(). Более эффективные методики приходят….
relation() может принимать в качестве первого аргумента вызываемую переменную, которая возвращает связанный класс. Это сделано для того, чтобы помочь декларативным пакетам определять отношения, не имея еще классов.
Добавлен новый оператор «более высокого уровня» «of_type()»: используется в join(), а также в any() и has(), определяет подкласс, который будет использоваться в критерии фильтрации, например:
- query.filter(Company.employees.of_type(Engineer).
any(Engineer.name==“foo“))
или
- query.join(Company.employees.of_type(Engineer)).
filter(Engineer.name==“foo“)
Превентивный код против потенциальной ошибки потери ссылок в flush().
Выражения, используемые в filter(), filter_by() и других, при использовании условия, сформированного на основе отношения, использующего идентификатор дочернего объекта (например, filter(Parent.child==<somechild>)), оценивают фактическое значение первичного ключа <somechild> во время выполнения, чтобы этап автопромывки запроса мог завершиться, тем самым заполняя значение PK <somechild> в случае, если <somechild> был в ожидании.
установка порядка по на уровне relation()для столбца во «вторичной» таблице типа «многие-ко-многим» теперь работает при ускоренной загрузке, ранее «порядок по» не был привязан к псевдониму вторичной таблицы.
Синонимы, накладывающиеся на существующие дескрипторы, теперь являются полноценными прокси для этих дескрипторов.
sql¶
Можно снова создавать псевдонимы селектов для текстовых предложений FROM.
References: #975
Значением bindparam() может быть вызываемая переменная, в этом случае она оценивается во время выполнения оператора для получения значения.
Добавлена поддержка обёртывания исключений/переподключения при получении набора результатов. Переподключение работает для тех баз данных, которые при получении результатов выдают улавливаемую ошибку данных (т.е. не работает на MySQL)
References: #978
Реализован двухфазный API для «потокового» движка, через engine.begin_twophase(), engine.prepare()
References: #936
Исправлена ошибка, из-за которой UNIONS не могли быть клонированы.
References: #986
Добавлен аргумент ключевого слова «bind» для операторов insert(), update(), delete() и DDL(). Свойство .bind теперь можно присваивать этим операторам, а также select().
Операторы вставки теперь могут быть скомпилированы с дополнительными «префиксными» словами между INSERT и INTO для расширений производителя, таких как INSERT IGNORE INTO таблицы MySQL.
extensions¶
добавлено новое сверхмалое «декларативное» расширение, позволяющее конфигурировать таблицы и mapper() в строке под объявлением класса. Это расширение отличается от ActiveMapper и Elixir тем, что оно вообще не переопределяет семантику SQLAlchemy; для определения поведения класса и определения таблицы используются литеральные конструкции Column, Table и relation().
misc¶
Некорректные URL-адреса соединений SQLite теперь вызывают ошибку.
Postgres TIMESTAMP отображается корректно
References: #981
Postgres PGArray по умолчанию является типом «mutable»; при использовании с ORM для проверки изменений используются методы проверки равенства/копирования при записи в стиле mutable.
0.4.3¶
Released: Thu Feb 14 2008general¶
Исправлено множество скрытых и не совсем скрытых проблем совместимости с Python 2.3, благодаря новой поддержке запуска полного набора тестов на 2.3.
Предупреждения теперь выдаются в виде исключений типа.SAWarning.
orm¶
Теперь каждый сеанс Session.begin() должен сопровождаться соответствующим commit() или rollback(), если только сеанс не закрыт с помощью Session.close(). Это также относится к begin(), которая неявно выполняется для сессии, созданной с transactional=True. Самым большим изменением здесь является то, что если сессия, созданная с transactional=True, вызывает исключение во время flush(), то для продолжения работы сессии после исключения необходимо вызвать Session.rollback() или Session.close().
Исправлена ошибка удвоения коллекции merge() при слиянии переходных сущностей с коллекциями с обратной ссылкой.
References: #961
merge(dont_load=True) не принимает переходные сущности, что является продолжением того, что merge(dont_load=True) также не принимает «грязные» объекты.
Добавлен отдельный атрибут класса «query», генерируемый scoped_session. Это позволяет получить MyClass.query без использования Session.mapper. Используется через:
MyClass.query = Session.query_property()
При попытке получить доступ к атрибутам экземпляра с истекшим сроком действия при отсутствии сессии выдается соответствующее сообщение об ошибке
dynamic_loader() / lazy=»dynamic» теперь принимает и использует параметр order_by так же, как это происходит с relation().
В сессию добавлен метод expire_all(). Вызывает expire() для всех постоянных экземпляров. Это удобно в сочетании с…
У экземпляров, срок действия которых был частично или полностью истек, атрибуты с истекшим сроком будут заполнены при выполнении обычной операции Query, затрагивающей эти объекты, что позволяет избежать ненужного второго SQL-оператора для каждого экземпляра.
Динамические отношения, когда на них ссылаются, создают сильную ссылку на родительский объект, так что у запроса остается родитель для обращения к нему, даже если родитель создается (и разыменовывается) только в пределах одного выражения.
References: #938
Добавлен флаг mapper() «eager_defaults». Если он установлен в значение True, то значения по умолчанию, генерируемые во время операций INSERT или UPDATE, пост-фетишируются немедленно, а не откладываются на потом. Это имитирует поведение старой версии 0.3.
query.join() теперь может принимать в качестве аргументов атрибуты, отображаемые на классы. Они могут использоваться вместо строк или в любой их комбинации. В частности, это позволяет строить соединения с подклассами на основе полиморфного отношения, т.е:
query(Company).join([„employees“, Engineer.name])
query.join() также может принимать в качестве аргументов кортежи имен атрибутов/некоторых selectable. Это позволяет строить объединения из подклассов полиморфного отношения, т.е:
query(Company).join(
)
Общие улучшения поведения join() при работе с полиморфными отображениями, т.е. объединение от/к полиморфным отображениям и корректное применение псевдонимов.
Исправлено/доработано поведение, когда картограф определяет естественный «первичный ключ» сопоставленного соединения, он будет более эффективно сокращать столбцы, эквивалентные по отношению к внешнему ключу. Это, в частности, влияет на количество аргументов, передаваемых в query.get().
References: #933
Ленивый загрузчик теперь может обрабатывать условие объединения, когда «связанный» столбец (т.е. тот, которому в качестве параметра привязки передается идентификатор родителя) встречается в условии объединения более одного раза. В частности, это позволяет решить распространенную задачу relation(), содержащую связанный с родителем подзапрос, например, «выбрать только самый последний дочерний элемент».
References: #946
Исправлена ошибка в полиморфном наследовании, при которой возникало некорректное исключение, когда базовый столбец polymorphic_on не соответствовал ни одному столбцу в локальном selectable наследующего mapper более чем на один уровень глубже.
Исправлена ошибка в полиморфном наследовании, из-за которой было сложно установить рабочий «order_by» для полиморфного отображателя.
Исправлен довольно дорогой вызов в Query, который замедлял выполнение полиморфных запросов.
»Пассивные умолчания» и другие «встроенные» умолчания теперь при необходимости могут быть загружены во время вызова flush(); в частности, это позволяет строить relations(), в которых столбец с внешним ключом ссылается на сгенерированный на стороне сервера столбец, не являющийся первичным ключом.
References: #954
- Дополнительные исправления/изменения транзакций сеанса:
Исправлена ошибка с управлением транзакциями сеансов: при добавлении соединения во вложенную транзакцию родительские транзакции не запускались на соединении.
Теперь session.transaction всегда ссылается на самую внутреннюю активную транзакцию, даже если commit/rollback вызываются непосредственно на объекте транзакции сессии.
Теперь можно готовить двухфазные транзакции.
При сбое подготовки двухфазной транзакции на одном соединении происходит откат всех соединений.
session.close() не закрывал все транзакции при использовании вложенных транзакций.
Ранее функция rollback() ошибочно устанавливала текущую транзакцию непосредственно в родительскую транзакцию, на которую можно было откатиться. Теперь она откатывается на следующую транзакцию, которая может это сделать, но устанавливает текущую транзакцию на ее родителя и инактивирует транзакции, находящиеся между ними. Неактивные транзакции могут быть только откачены или закрыты, любой другой вызов приводит к ошибке.
autoflush для commit() не очищался для простых субтранзакций.
unitofwork flush не закрывал неудачную транзакцию, когда сессия не находилась в транзакции и фиксация транзакции была неудачной.
Разные билеты:
sql¶
Добавлен «schema.DDL», исполняемый оператор DDL произвольной формы. DDL могут выполняться изолированно или быть прикреплены к экземплярам таблиц или метаданных и выполняться автоматически при создании и/или удалении этих объектов.
Столбцы и ограничения таблицы могут быть переопределены для существующей таблицы (например, таблицы, которая уже была отражена) с помощью флага „useexisting=True“, который теперь учитывает переданные вместе с ним аргументы.
Добавлен вызываемый интерфейс событий DDL, добавлены хуки до и после создания и сброса таблиц и метаданных.
В конструкции delete() и update() добавлен генеративный метод where(<критерий>), который возвращает новый объект с критерием, присоединенным к существующему критерию через AND, подобно select().where().
В операции с колонками добавлен оператор «ilike()». Компилируется в ILIKE для postgres, lower(x) LIKE lower(y) для всех остальных.
References: #727
Добавлена общая функция «now()»; на SQLite, Oracle и MSSQL компилируется как «CURRENT_TIMESTAMP»; «now()» - на всех остальных.
References: #943
Операторы startswith(), endswith() и contains() теперь конкатенируют оператор подстановки с заданным операндом в SQL, т.е. «“%“ || <bindparam>» во всех случаях, корректно принимают операнды text(„something“)
References: #962
cast() корректно принимает text(„something“) и другие нелитеральные операнды
References: #962
Исправлена ошибка в прокси-сервере результатов, когда метки столбцов, сгенерированные анонимно, не были доступны по их прямому строковому имени
Теперь можно определить откладываемые ограничения.
Добавлен ключевой аргумент «autocommit=True» в select() и text(), а также генеративный метод autocommit() в select(); для операторов, модифицирующих базу данных какими-либо определенными пользователем средствами, отличными от обычных INSERT/UPDATE/ DELETE и т.д. Этот флаг включает поведение «autocommit» во время выполнения, если транзакция не находится в процессе.
References: #915
Атрибут „.c.“ селектора теперь получает запись для каждого выражения столбца в его предложении columns. Ранее «безымянные» столбцы, такие как функции и CASE-операторы, туда не помещались. Теперь они попадают туда, используя полное строковое представление, если нет „name“.
CompositeSelect, т.е. любой union(), union_all(), intersect() и т.д. теперь утверждает, что каждый selectable содержит одинаковое количество столбцов. Это соответствует соответствующему требованию SQL.
Анонимная «метка», генерируемая для немаркированных функций и выражений, теперь распространяется наружу во время компиляции для выражений типа select([select([func.foo()])]).
Развивая вышеизложенные идеи, CompositeSelects теперь формирует свою коллекцию «.c.» на основе имен, присутствующих только в первом селекте; функция corresponding_column() теперь работает полностью для всех встроенных селектов.
Oracle и другие компании правильно кодируют SQL, используемый для умолчаний, таких как последовательности и т.д., даже если не используются юникодовые идентификаторы, поскольку программа подготовки идентификаторов может вернуть кэшированный юникодовый идентификатор.
Сравнение столбцов и клаузул с объектами datetime в левой части выражения теперь работает (d < table.c.col). (Временные объекты с левой стороны всегда работали, исключение с левой стороны является причудой реализации datetime).
misc¶
Улучшена поддержка схем в SQLite (связанных с ATTACH DATABASE … AS name). В некоторых случаях в прошлом имена схем опускались в генерируемом SQL для SQLite. Теперь это не так.
table_names в SQLite теперь подхватывает и временные таблицы.
Автоопределение неопределенного режима MySQL ANSI_QUOTES при выполнении операций отражения, поддержка изменения режима в середине пути. Ручная установка режима по-прежнему требуется, если отражение не используется.
Исправлено отражение столбцов TIME на SQLite.
Наконец-то добавлен тип PGMacAddr в postgres
References: #580
Отражение последовательности, связанной с полем PK (обычно с помощью триггера BEFORE INSERT) в Firebird
При генерации подзапроса LIMIT/OFFSET Oracle собирает правильные столбцы в сопоставлении столбцов результирующего набора, что позволяет правильно сопоставлять столбцы с результирующими наборами, даже если применяется усечение длинных имен
References: #941
MSSQL теперь включает EXEC в регексп _is_select, что должно позволить использовать хранимые процедуры с возвратом строк.
В MSSQL появилась экспериментальная реализация LIMIT/OFFSET с использованием функции ANSI SQL row_number(), поэтому для ее использования требуется MSSQL-2005 или более поздняя версия. Чтобы включить эту функцию, добавьте «has_window_funcs» в аргументы ключевого слова для connect или добавьте «?has_window_funcs=1» в аргументы запроса dburi.
Изменен ext.activemapper для использования нетранзакционной сессии для хранилища объектов.
Исправлен порядок вывода бинарной операции «[„a“] + obj.proxied» для ассоциативно-проксированных списков.
0.4.2p3¶
Released: Wed Jan 09 2008general¶
Схема нумерации версий изменена в соответствии с правилами нумерации версий setuptools; easy_install -u теперь должен получить версию выше 0.4.2.
orm¶
Исправлена ошибка с session.dirty при использовании «мутабельных скаляров» (таких как PickleTypes)
добавлено более наглядное сообщение об ошибке при очистке отношения(), имеющего нелокально отображаемые столбцы в первичном или вторичном условии присоединения
теперь подавление всех ошибок в InstanceState.__cleanup().
Исправлена ошибка, связанная с тем, что при назначении новой коллекции атрибуту, основанному на коллекции, в который уже были внесены изменения, генерировалась некорректная история
References: #922
Исправлена ошибка каскадного удаления сирот, когда при установке одного и того же объекта дважды на скалярный атрибут он мог быть занесен в журнал как сирота
References: #925
Исправлены каскады при присваивании += отношению, основанному на списке.
Теперь синонимы могут создаваться для несуществующих реквизитов, которые впоследствии добавляются с помощью функции add_property(). Это обычно включает в себя обратные ссылки. (т.е. вы можете создавать синонимы для backrefs, не заботясь о порядке выполнения операций)
References: #919
Исправлена ошибка, которая могла возникнуть при использовании полиморфного отображателя «union», возвращающегося к «отложенной» загрузке наследуемых таблиц
коллекция «columns» на mapper/mapped class (т.е. „c“) относится к mapped table, а не к select_table в случае полиморфной загрузки «union» (это не должно быть заметно).
Исправлена достаточно критичная ошибка, из-за которой один и тот же экземпляр мог быть указан в коллекции unitofwork.new более одного раза; наиболее типично это проявлялось при использовании комбинации наследующих мапперов и ScopedSession.mapper, так как многократные вызовы __init__ для каждого экземпляра могли сохранить() объект с разными _state объектами
добавлено очень рудиментарное поведение итератора yielding в Query. Вызовите query.yield_per(<количество строк>) и оцените Query в итеративном контексте; каждая коллекция из N строк будет упакована и выдана. Используйте этот метод с особой осторожностью, так как он не пытается согласовать загруженные с нетерпением коллекции через границы пакетов результатов, а также не будет вести себя хорошо, если один и тот же экземпляр встречается в нескольких пакетах. Это означает, что коллекция, загруженная с нетерпением, будет очищена, если на нее ссылаются более чем в одной партии, и во всех случаях атрибуты будут перезаписаны у экземпляров, встречающихся более чем в одной партии.
Исправлены операторы мутации множеств на месте для коллекций множеств и ассоциативно-проксимированных множеств.
References: #920
sql¶
Тип Text теперь экспортируется корректно и не вызывает предупреждения при создании DDL; типы String без длины вызывают предупреждение только при создании CREATE TABLE
References: #912
добавлен новый тип UnicodeText для задания кодированного, не удлиненного типа Text
Исправлена ошибка в union(), так что операторы select(), не являющиеся производными от объектов FromClause, могут быть объединены в союз
изменено название TEXT на Text, так как это «общий» тип; название TEXT устарело до 0.5. «Обновление» поведения String в Text при отсутствии длины также устарело до 0.5; при использовании в операторах CREATE TABLE будет выдаваться предупреждение (String без длины для целей SQL-выражения по-прежнему подходит).
References: #912
Генеративный select.order_by(None) / group_by(None) не справлялся со сбросом критерия order by/group by, исправлено
References: #924
misc¶
Исправлено отражение в mysql пустых строк столбцов по умолчанию.
“+“, „*“, „+=“ и „*=“ для ассоциативных прокси-списков.
mssql - сужена проверка на «date»/»datetime» в подклассах MSDate/ MSDateTime, чтобы входящие объекты «datetime» не интерпретировались как объекты «date» и наоборот.
References: #923
Исправлено отсутствие вызова обработчика результатов подтипа для типа PGArray.
References: #913
0.4.2¶
Released: Wed Jan 02 2008orm¶
существенное изменение в поведении обратных ссылок на коллекции: они больше не вызывают ленивую загрузку! «Обратные» добавления и удаления ставятся в очередь и объединяются с коллекцией в момент ее чтения и загрузки, но не вызывают предварительной загрузки. Для пользователей, которые заметили такое поведение, это должно быть гораздо удобнее, чем использование динамических отношений в некоторых случаях; для тех, кто не заметил, вы можете заметить, что ваши приложения используют гораздо меньше запросов, чем раньше, в некоторых ситуациях.
References: #871
Добавлена поддержка мутабельных первичных ключей. Столбцы первичного ключа могут быть свободно изменены, при этом идентификатор экземпляра будет меняться при промывке. Кроме того, поддерживаются каскады обновлений ссылок на внешний ключ (первичный ключ или нет) в отношениях, либо в тандеме с ON UPDATE CASCADE базы данных (требуется для таких БД, как Postgres), либо непосредственно ORM в виде операторов UPDATE, с установкой флага «passive_cascades=False».
Наследуемые картографы теперь напрямую наследуют MapperExtensions своего родительского картографа, так что все методы конкретного MapperExtension вызываются и для подклассов. Как обычно, любое MapperExtension может возвращать либо EXT_CONTINUE для продолжения обработки расширения, либо EXT_STOP для прекращения обработки. Порядок разрешения маппера следующий: <расширения, объявленные на маппере классов> <расширения, объявленные на родительском маппере классов> <объявленные глобально расширения>.
Обратите внимание, что если инстанцировать один и тот же класс расширения отдельно, а затем применить его по отдельности для двух отображателей в одной цепочке наследования, то расширение будет дважды применено к наследующему классу, и каждый метод будет вызван дважды.
Чтобы явно применить расширение mapper к каждому наследующему классу, но чтобы каждый метод вызывался только один раз за операцию, используйте один и тот же экземпляр расширения для обоих mapper’ов.
References: #490
MapperExtension.before_update() и after_update() теперь вызываются симметрично; ранее экземпляр, не имеющий измененных атрибутов столбцов (но имеющий модификацию relation()), мог быть вызван с помощью before_update(), но не after_update()
References: #907
столбцы, отсутствующие в операторе select запроса, теперь автоматически откладываются при загрузке.
Сопоставленные классы, расширяющие «object» и не предоставляющие метод __init__(), теперь будут выдавать ошибку TypeError, если во время конструирования экземпляра присутствуют непустые *args или **kwargs (и не используются никакими расширениями, такими как scoped_session mapper), что соответствует поведению обычных классов Python
References: #908
Исправлена ошибка в запросе, когда функция filter_by() сравнивает отношение с None
References: #899
улучшена поддержка пикирования отображаемых сущностей. Ленивые/отложенные/истекшие callables теперь сериализуемы, так что они сериализуются и десериализуются с _state.
Новое поведение функции synonym(): во всех случаях на отображаемый класс будет помещен атрибут, если такового еще не существует. Если свойство на классе уже существует, то синоним украсит свойство соответствующими операторами сравнения, чтобы его можно было использовать в выражениях колонок, как и любой другой отображаемый атрибут (т.е. использовать в filter() и т.д.) Флаг «proxy=True» устарел и больше ничего не значит. Кроме того, флаг «map_column=True» автоматически генерирует свойство ColumnProperty, соответствующее имени синонима, т.е.: „somename“:synonym(„_somename“, map_column=True) сопоставит колонку с именем „somename“ атрибуту „_somename“. Смотрите пример в документации по картографу.
References: #801
Query.select_from() теперь заменяет все существующие критерии FROM на заданный аргумент; прежнее поведение, заключавшееся в построении списка предложений FROM, в общем случае было бесполезным, поскольку для создания критерия присоединения требовалось вызывать filter(), а новые таблицы, вводимые в рамках filter(), уже сами добавляют себя в предложение FROM. Новое поведение позволяет использовать не только присоединения из главной таблицы, но и операторы select. Критерий фильтра, порядок по, клаузулы с нетерпеливой загрузкой будут «алиасированы» по отношению к данному оператору.
Рефакторинг инструментария атрибутов, проведенный в этом месяце, изменяет поведение «копирование при загрузке», которое мы имеем с середины версии 0.3, на «копирование при модификации» в большинстве случаев. Это устраняет значительную часть задержек в операциях загрузки и в целом делает меньше работы, так как копируются только те атрибуты, которые действительно были изменены, их «зафиксированное состояние». Только «мутируемые скалярные» атрибуты (т.е. pickled-объект или другой мутируемый элемент), которые и были причиной изменения copy-on-load, сохраняют старое поведение.
Небольшое изменение в поведении атрибутов заключается в том, что удаление атрибута не вызывает повторного срабатывания ленивого загрузчика этого атрибута; при «del» эффективное значение атрибута становится «None». Чтобы повторно запустить «загрузчик» атрибута, используйте session.expire(instance,).
query.filter(SomeClass.somechild == None) при сравнении свойства «многие-к-одному» с None корректно выдает «id IS NULL», включая то, что NULL находится в правой части.
query.order_by() учитывает aliased joins, т.е. query.join(„orders“, aliased=True).order_by(Order.id)
eagerload(), lazyload(), eagerload_all() принимают необязательный второй аргумент class-or-mapper, который позволяет выбрать отображение, к которому будет применена опция. Он может быть выбран среди других отображателей, которые были добавлены с помощью функции add_entity().
eagerloading будет работать с картографами, добавленными с помощью функции add_entity().
Если флаг passive_deletes (также только что добавленный) не установлен, то удаление родительского элемента вызовет полную загрузку дочерних элементов, чтобы они могли быть удалены или обновлены соответствующим образом.
также с динамическим, реализовано корректное поведение count(), а также другие вспомогательные методы.
исправление каскадов на полиморфных отношениях, заключающееся в том, что каскады от объекта к полиморфной коллекции продолжают каскадироваться по набору атрибутов, характерных для каждого элемента коллекции.
query.get() и query.load() не учитывают существующий фильтр или другой критерий; эти методы всегда ищут заданный идентификатор в базе данных или возвращают текущий экземпляр из карты идентификации, не обращая внимания на любой существующий фильтр, join, group_by или другой критерий, который был настроен.
References: #893
добавлена поддержка version_id_col в сочетании с наследуемыми картографами. version_id_col обычно устанавливается на базовом картографе в отношениях наследования, где он вступает в силу для всех наследуемых картографов.
References: #883
смягчены правила для выражений column_property(), имеющих метки; теперь принимается любой ColumnElement, так как компилятор автоматически помечает ColumnElements без меток. selectable, как и оператор select(), по-прежнему требует преобразования в ColumnElement через as_scalar() или label().
Исправлена ошибка обратной ссылки, когда нельзя было del instance.attr, если attr был None
удалены или стали частными несколько ORM-атрибутов: mapper.get_attr_by_column(), mapper.set_attr_by_column(), mapper.pks_by_table, mapper. cascade_callable(), MapperProperty.cascade_callable(), mapper.canload(), mapper.save_obj(), mapper.delete_obj(), mapper._mapper_registry, attributes.AttributeManager
Присвоение атрибуту отношения несовместимого типа коллекции теперь вызывает ошибку TypeError, а не ArgumentError, как в sqlalchemy.
При массовом присваивании коллекции MappedCollection теперь возникает ошибка, если ключ во входящем словаре не совпадает с ключом, который будет использоваться для этого значения в функции keyfunc коллекции.
References: #886
В пользовательских коллекциях теперь можно указать метод @converter для преобразования объектов, используемых при «массовом» присвоении, в поток значений, как в примере:
obj.col = # or obj.dictcol = {'foo': newval1, 'bar': newval2}
MappedCollection использует этот хук для того, чтобы убедиться, что входящие пары ключ/значение являются нормальными с точки зрения коллекции.
исправлена проблема бесконечного цикла при использовании lazy=»dynamic» на обеих сторонах двунаправленной связи
References: #872
Исправлено искажение LIMIT/OFFSET при использовании Query + eagerloads, в данном случае при сопоставлении с оператором select
References: #904
исправление самореферентной ускоренной загрузки, в результате которого, если один и тот же экземпляр mapped появляется в двух или более различных наборах столбцов в одном наборе результатов, его ускоренно загружаемая коллекция будет заполнена независимо от того, все ли строки содержат набор «ускоренных» столбцов для этой коллекции. это также будет проявляться как KeyError при получении результатов с включенным join_depth.
Исправлена ошибка, при которой Query не применял подзапрос к SQL, когда LIMIT использовался в сочетании с наследуемым маппером, где eager loader находился только в родительском маппере.
уточнено сообщение об ошибке, возникающей при попытке обновить() экземпляр с тем же идентификационным ключом, что и экземпляр, уже присутствующий в сеансе.
некоторые уточнения и исправления в merge(instance, dont_load=True). исправлена ошибка, при которой на возвращаемых экземплярах отключались ленивые загрузчики. Кроме того, в настоящее время мы не поддерживаем слияние экземпляров с незафиксированными изменениями, в случае использования dont_load=True…. это приведет к ошибке. Это связано со сложностями при слиянии «зафиксированного состояния» данного экземпляра для корректного соответствия вновь скопированному экземпляру, а также других измененных состояний. Так как использование dont_load=True связано с кэшированием, то в данном экземпляре в любом случае не должно быть никаких незафиксированных изменений. Мы также копируем экземпляры без использования каких-либо событий, так что «грязный» список в новой сессии остается незатронутым.
Исправлена ошибка, которая могла возникнуть при использовании session.begin_nested() в сочетании с более чем на один уровень вглубь вложенными утверждениями session.begin()
исправлена работа функции session.refresh() с экземпляром, имеющим пользовательское имя entity_name
References: #914
sql¶
общие функции ! мы вводим базу данных известных функций SQL, таких как current_timestamp, coalesce, и создаем явные объекты функций, представляющие их. Эти объекты имеют ограниченные списки аргументов, знают типы и могут компилироваться в зависимости от диалекта. Так, если func.char_length(«foo», «bar») выдает ошибку (слишком много аргументов), то func.coalesce(datetime.date(2007, 10, 5), datetime.date(2005, 10, 15)) знает, что ее возвращаемый тип - Date. Пока у нас представлено только несколько функций, но мы будем продолжать пополнять систему
References: #615
улучшена поддержка автоматического переподключения; теперь Connection может автоматически переподключаться после того, как его базовое соединение аннулировано, без необходимости повторного подключения() от движка. Это позволяет ORM-сессии, привязанной к одному Connection, не нуждаться в переподключении. Открытые транзакции на Connection должны быть откачены после аннулирования базового соединения, иначе будет выдана ошибка. Также исправлена ошибка, из-за которой функция disconnect detect не вызывалась для cursor(), rollback() или commit().
добавлен новый флаг в String и create_engine(), assert_unicode=(True|False|“warn“|None). По умолчанию имеет значение False или None для create_engine() и String, „warn“ для типа Unicode. Если True, то все операции преобразования в юникод вызывают исключение, когда в качестве параметра привязки передается неюникодная байтовая строка. „warn“ приводит к выдаче предупреждения. Настоятельно рекомендуется, чтобы все приложения с поддержкой юникода правильно использовали объекты юникода Python (например, u’hello“, а не „hello“) для точного обхода данных.
Генерация «уникальных» параметров связывания была упрощена до использования тех же механизмов «уникального идентификатора», что и все остальное. Это не затрагивает пользовательский код, за исключением кода, который мог быть жестко закодирован в соответствии с генерируемыми именами. Генерируемые параметры связывания теперь имеют вид «<paramname>_<num>», тогда как раньше такой вид имел только второй одноименный параметр связывания.
select().as_scalar() вызовет исключение, если select не содержит ровно одного выражения в предложении columns.
Сами объекты bindparam() могут использоваться в качестве ключей для execute(), т.е. statement.execute({bind1:“foo“, bind2:“bar“})
в TypeDecorator добавлены новые методы process_bind_param() и process_result_value(), которые автоматически используют преимущества обработки базового типа. Идеально подходят для использования с Unicode или Pickletype. TypeDecorator теперь должен стать основным способом дополнения поведения любого существующего типа, включая другие подклассы TypeDecorator, такие как PickleType.
selectables (и другие) будут выдавать предупреждение, если два столбца в их экспортируемой коллекции столбцов конфликтуют по имени.
Таблицы со схемами могут по-прежнему использоваться в sqlite, firebird, имя схемы просто отбрасывается
References: #890
Изменены различные функции генерации «литералов» для использования анонимного параметра привязки. Здесь мало что изменилось, разве что их метки теперь выглядят как «:param_1», «:param_2» вместо «:literal».
Теперь поддерживаются метки столбцов в виде «tablename.columname», т.е. с точкой.
Ключевой аргумент from_obj в select() может быть скаляром или списком.
misc¶
Тип sqlite SLDate не будет ошибочно отображать часть «микросекунды» объекта datetime или time.
- oracle
добавлена поддержка обнаружения разъединения для Oracle
некоторая очистка бинарных/сырьевых типов, чтобы cx_oracle.LOB обнаруживался на специальной основе
References: #902
- M
В PyODBC больше нет глобального параметра «set nocount on».
Исправление неидентичных целочисленных PK при автозагрузке
Улучшенная поддержка convert_unicode
Менее строгое преобразование даты для pyodbc/adodbapi
Таблицы с квалификацией схемы / автозагрузка
правильно отражает домены (частичное исправление), а PassiveDefaults
References: #410
возврат к использованию класса пула по умолчанию (в 0.4.0 для тестовых целей был установлен SingletonThreadPool)
map func.length() to „char_length“ (легко переопределяется с помощью UDF „strlen“ в старых версиях Firebird)
0.4.1¶
Released: Sun Nov 18 2007orm¶
Ускоренная загрузка с применением LIMIT/OFFSET больше не добавляет первичную таблицу, присоединенную к ограниченному подзапросу самой себя; теперь ускоренная загрузка присоединяется непосредственно к подзапросу, который также предоставляет столбцы первичной таблицы в набор результатов. Это исключает JOIN из всех ускоренных загрузок с LIMIT/OFFSET.
References: #843
session.refresh() и session.expire() теперь поддерживают дополнительный аргумент «attribute_names» - список индивидуальных ключевых имен атрибутов, которые должны быть обновлены или исключены, что позволяет частично перезагружать атрибуты на уже загруженном экземпляре.
References: #802
добавлен оператор op() для инструментальных атрибутов, т.е. User.name.op(„ilike“)(„%somename%“)
References: #767
Сопоставленные классы теперь могут определять методы __eq__, __hash__ и __nonzero__ с произвольной семантикой. Orm теперь обрабатывает все сопоставленные экземпляры только на основе идентификации. (например, „is“ против „==“).
References: #676
Убран аксессор «properties» для Mapper; теперь он выбрасывает информативное исключение, объясняющее использование mapper.get_property() и mapper.iterate_properties
В Query добавлен метод having(), который применяет HAVING к формируемому утверждению так же, как filter() применяет к предложению WHERE.
Поведение query.options() теперь полностью основано на путях, т.е. такая опция, как eagerload_all(„x.y.z.y.x“) будет применять eagerloading только к этим путям, т.е. не к „x.y.x“; eagerload(„children.children“) применяется только к путям глубиной ровно в два уровня и т.д.
References: #777
PickleType при установке mutable=False будет сравнивать, используя ==, а не оператор is. Чтобы использовать is или любой другой компаратор, отправьте пользовательскую функцию сравнения с помощью PickleType(comparator=my_custom_comparator).
Запрос не выдает ошибку, если использовать distinct() и order_by(), содержащие UnaryExpressions (или другие) вместе
References: #848
Выражения order_by() из объединенных таблиц корректно добавляются в предложение columns при использовании distinct()
References: #786
Исправлена ошибка, при которой Query.add_column() не принимал в качестве аргумента атрибут, связанный с классом; Query также выдает ошибку, если в add_column() передан недопустимый аргумент (в момент времени instances())
References: #858
добавлена дополнительная проверка на наличие разыменований мусорных коллекций в InstanceState.__cleanup() для уменьшения количества ошибок «gc ignored» при завершении работы приложения
Утвержден сессионный API:
Ошибка заключается в том, что session.save() сохраняет объект, который уже является постоянным
References: #840
Ошибка заключается в том, что session.delete() удаляет объект, который не является постоянным.
session.update() и session.delete() приводят к ошибке при обновлении или удалении экземпляра, который уже находится в сессии с другим идентификатором.
Сессия более тщательно проверяет, когда определяет, что «объект X уже находится в другой сессии»; например, если вы пикетируете ряд объектов и распикируете их (т.е. как в HTTP-сессии Pylons или аналогичной), они могут попасть в новую сессию без какого-либо конфликта
В функции merge() присутствует ключевой аргумент «dont_load=True». Установка этого флага приведет к тому, что операция слияния не будет загружать данные из базы данных в ответ на входящие отсоединенные объекты, а будет принимать входящий отсоединенный объект так, как будто он уже присутствует в данной сессии. Используйте этот флаг для слияния в сессию отсоединенных объектов из внешних систем кэширования.
Отложенные атрибуты столбцов больше не вызывают операцию загрузки при назначении атрибута. В этих случаях вновь присвоенное значение будет присутствовать в операторе UPDATE флеша безусловно.
Исправлена ошибка усечения при переназначении подмножества коллекции (obj.relation = obj.relation[1:])
References: #834
Устранен крафтовый код конфигурации обратных ссылок, теперь обратные ссылки, которые наступают на существующие свойства, вызывают ошибку
References: #832
Улучшено поведение add_property() и т.д., исправлена ситуация с синонимом/деферентом.
References: #831
Исправлено поведение функции clear_mappers() для лучшей самоочистки.
Исправлено поведение «переключения рядов», т.е. когда INSERT/DELETE объединяются в один UPDATE, отношения «многие-ко-многим» на родительском объекте обновляются корректно.
References: #841
Исправлен __hash__ для ассоциативных proxy - эти коллекции являются нехешируемыми, как и их мутабельные аналоги в Python.
Добавлено проксирование методов save_or_update, __contains__ и __iter__ для скопированных сессий.
Исправлена очень трудновоспроизводимая проблема, при которой предложение FROM в запросе могло быть загрязнено некоторыми генеративными вызовами
References: #852
sql¶
ключевой параметр «shortname» в функции bindparam() был устаревшим.
Добавлен оператор contains (генерирует предложение «LIKE %<другой>%»).
Выражения анонимных столбцов автоматически маркируются. Например, select([x* 5]) выдает «SELECT x * 5 AS anon_1». Это позволяет включить метку в cursor.description, которая затем может быть соответствующим образом сопоставлена с правилами обработки столбцов результатов. (Мы не можем надежно использовать позиционное отслеживание для соответствия столбцам результатов, поскольку выражения text() могут представлять несколько столбцов).
Перегрузка операторов теперь управляется объектами TypeEngine - пока что единственной встроенной перегрузкой операторов является перегрузка типа String в оператор конкатенации строк „+“. Пользовательские типы также могут определять свою собственную перегрузку операторов, переопределяя метод adapt_operator(self, op).
нетипизированным параметрам связывания в правой части бинарного выражения будет присвоен тип левой части операции, чтобы обеспечить соответствующую обработку параметров связывания
References: #819
Удален шаг регулярных выражений из большинства компиляций операторов. Также исправлен
References: #833
Исправлены пустые (с нулевым столбцом) sqlite-вставки, разрешены вставки в автоинкрементные одностолбцовые таблицы.
Исправлена трансляция выражений в выражениях text(); это устраняет различные ORM-сценарии, в которых в SQL-выражениях используется буквальный текст
Удален объект ClauseParameters; теперь compiled.params возвращает обычный словарь, а также result.last_inserted_params() / last_updated_params().
Исправлены операторы INSERT для столбцов с первичным ключом, для которых установлены генераторы по умолчанию на основе SQL-выражений; SQL-выражение выполняется в обычном режиме, но не запускает условие «postfetch» для столбца, для тех БД, которые обеспечивают это через cursor.lastrowid
func. объекты могут быть маринованными/немаринованными
References: #844
переработана и упрощена система, используемая для «нацеливания» столбцов на выбираемые выражения. На стороне SQL это представлено методом «corresponding_column()». Этот метод активно используется ORM для «адаптации» элементов выражения к аналогичным, псевдослучайным выражениям, а также для нацеливания столбцов результирующего набора, изначально привязанных к таблице или селектируемых по псевдослучайному, «соответствующему» выражению. В новом варианте переписанное выражение ведет себя абсолютно последовательно и точно.
Добавлено поле («info») для хранения произвольных данных об элементах схемы
References: #573
Коллекция «properties» в Connections была переименована в «info», чтобы соответствовать коллекциям schema с возможностью записи. До версии 0.5 доступ к ней по-прежнему будет осуществляться через имя «properties».
исправлен метод close() для Transaction при использовании strategy=“threadlocal“
Исправление компилированных параметров привязки, чтобы они ошибочно не заполнялись None
References: #853
<Engine|Connection>._execute_clauseelement становится публичным методом Connectable.execute_clauseelement
misc¶
Добавлена экспериментальная поддержка MaxDB (только версии >= 7.6.03.007).
Теперь oracle будет отражать «DATE» как колонку OracleDateTime, а не OracleDate
добавлено понимание имени схемы в функции oracle table_names(), исправлено metadata.reflect(schema=“someschema“)
References: #847
Анонимные метки MSSQL для выбора функций стали детерминированными
sqlite будет отражать «DECIMAL» как числовой столбец.
Повышена надежность определения дао доступа
References: #828
Переименован атрибут Dialect „preexecute_sequences“ в „preexecute_pk_sequences“. Для диалектов вне дерева, использующих старое название, создан прокси-атрибут.
Добавлено тестовое покрытие для отражения неизвестных типов. Исправлена работа sqlite/mysql с отражением типов для неизвестных типов.
Добавлен REAL для диалекта mysql (для тех, кто эксплуатирует sql-режим REAL_AS_FLOAT).
mysql Float, MSFloat и MSDouble, построенные без аргументов, теперь выдают DDL без аргументов, например, „FLOAT“.
Удалена неиспользуемая функция util.hash().
0.4.0¶
Released: Wed Oct 17 2007(начало основных изменений по сравнению с 0.3 см. в 0.4.0beta1, а также https://www.sqlalchemy.org/trac/wiki/WhatsNewIn04 )
Добавлена начальная поддержка Sybase (пока mxODBC)
References: #785
Добавлена поддержка частичных индексов для PostgreSQL. Используйте ключевое слово postgres_where в индексе.
Разбор параметров запроса на основе строк/разбор файла конфигурации понимает более широкий диапазон строковых значений для булевых значений
References: #817
Операция удаления объекта из backref не завершается, если коллекция другой стороны не содержит элемента, поддерживаются коллекции noload
References: #813
Удаление __len__ из «динамической» коллекции, так как это требовало бы выполнения SQL-операции «count()», что вынуждало бы все оценки списков выполнять избыточный SQL
References: #818
добавлены встроенные оптимизации в locate_dirty(), которые могут значительно ускорить повторные вызовы flush(), как это происходит при autoflush=True
References: #816
Тест IdentifierPreprarer’а на _requires_quotes теперь основан на регексе. Любые диалекты вне дерева, предоставляющие собственные наборы легальных_символов или нелегальных_инициальных_символов, должны будут перейти на регексы или переопределить _requires_quotes.
В Firebird значения supports_sane_rowcount и supports_sane_multi_rowcount установлены в False в соответствии с тикетом #370 (правильный путь).
- Улучшения и исправления в отражении Firebird:
FBDialect теперь подражает OracleDialect в части чувствительности к регистру имен TABLE и COLUMN (см. тему „case_sensitive remotion“ на этом файле).
FBDialect.table_names() не приводит к системным таблицам (ticket:796).
Теперь FB корректно отражает свойство Column как nullable.
Исправлено понимание компилятором SQL меток столбцов верхнего уровня, используемых при обработке набора результатов; вложенные селекты, содержащие одинаковые имена столбцов, не влияют на результат и не конфликтуют с метаданными столбцов результата.
query.get() и связанные с ней функции (например, many-to-one lazyloading) используют сглаженные во время компиляции имена параметров привязки, чтобы избежать конфликтов имен с параметрами привязки, которые уже существуют в отображаемом selectable.
Исправлена загрузка трех- и многоуровневого select и отложенного наследования (например, наследование abc при отсутствии select_table).
References: #795
Идентификатор, передаваемый в id_chooser в файле shard.py, всегда является списком.
Неарг ResultProxy._row_processor() теперь является атрибутом класса _process_row.
Добавлена поддержка возврата значений при вставках и обновлениях для PostgreSQL 8.2+.
References: #797
PG reflection, увидев, что имя схемы по умолчанию явно используется в качестве аргумента «schema» в таблице, предположит, что это желаемое пользователем соглашение, и будет явно задавать аргумент «schema» в отраженных таблицах, связанных с foreign-key, тем самым обеспечивая их соответствие только тем конструкторам таблиц, которые также используют явный аргумент «schema» (даже если это схема по умолчанию). Другими словами, SA предполагает, что пользователь последователен в этом использовании.
исправлено отражение в sqlite операций BOOL/BOOLEAN
References: #808
Добавлена поддержка UPDATE с LIMIT в mysql.
Нулевой внешний ключ на m2o не вызывает ленивую загрузку
References: #803
oracle не выполняет неявное преобразование в юникод для нетипизированных наборов результатов (т.е. когда даже не используется тип TypeEngine/String/Unicode; ранее он определял типы DBAPI и преобразовывал независимо от них). следует исправить
References: #800
исправление анонимной генерации меток для длинных имен таблиц/столбцов
References: #806
Диалект Firebird теперь использует SingletonThreadPool в качестве класса пула.
Firebird теперь использует dialect.preparer для форматирования имен последовательностей
Исправлен сбой при работе с postgres и несколькими двухфазными транзакциями. Двухфазные фиксации и откаты не приводили к автоматическому завершению новой транзакции, как это происходит при обычных фиксациях/откатах в dbapi.
References: #810
В расширение маппера _ScopedExt добавлена опция, позволяющая не сохранять автоматически новые объекты в сессию при инициализации объекта.
Исправлен синтаксис присоединения к Oracle не на языке ansi
Типы PickleType и Interval (на db, не поддерживающих их нативно) теперь работают немного быстрее.
В Firebird добавлены типы Float и Time (FBFloat и FBTime). Исправлен BLOB SUB_TYPE для типов TEXT и Binary.
Изменен API для оператора in_. Теперь in_() принимает один аргумент, представляющий собой последовательность значений или selectable. Старый API, в котором значения передавались как varargs, по-прежнему работает, но уже устарел.
0.4.0beta6¶
Released: Thu Sep 27 2007Карта идентификации сессий теперь по умолчанию имеет слабую ссылку, для использования обычной дикты используйте weak_identity_map=False. Используемая нами слабая диктанта настроена на обнаружение «грязных» экземпляров и сохранение временной сильной ссылки на эти экземпляры до тех пор, пока изменения не будут удалены.
Компиляция картографа была реорганизована таким образом, что большая часть компиляции происходит при построении картографа. Это позволяет сократить количество вызовов mapper.compile(), а также позволяет принудительно компилировать свойства, основанные на классах (например, User.addresses == 7 компилирует все мапперы; это так). Единственной оговоркой здесь является то, что наследующий отображатель теперь при построении ищет свой наследуемый отображатель, поэтому отображатели в рамках отношений наследования должны быть построены в порядке наследования (что в любом случае должно быть нормальным случаем).
References: #758
добавлено слово «FETCH» в число ключевых слов, определяемых Postgres для обозначения оператора удержания строки результата (т.е. в дополнение к «SELECT»).
Добавлен полный список зарезервированных ключевых слов SQLite, чтобы они правильно экранировались.
Уточнена связь между генерацией псевдонимов «нетерпеливой загрузки» в запросе и функцией Query.instances(), которая фактически захватывает нетерпеливо загруженные строки. Если алиасы не были специально сгенерированы EagerLoader для данного оператора, то EagerLoader не будет действовать при извлечении строк. Это предотвращает случайное захват столбцов в качестве части ускоренной загрузки, когда они для этого не предназначены, что может произойти при использовании текстового SQL, а также в некоторых ситуациях наследования. Это особенно важно, поскольку при «анонимном алиасинге» столбцов для генерации меток теперь используются простые целочисленные подсчеты.
Из clauseelement.compile() удален аргумент «parameters», он заменен на «column_keys». Параметры, передаваемые в execute(), взаимодействуют с процессом компиляции оператора вставки/обновления только в части имен столбцов, но не значений этих столбцов. Это обеспечивает более согласованное поведение execute/executemany и несколько упрощает внутреннюю работу.
Добавлен ключевой аргумент „comparator“ в PickleType. По умолчанию «мутабельный» PickleType выполняет «глубокое сравнение» объектов, используя их представление dumps(). Однако для словарей это не работает. Пиклируемые объекты, обеспечивающие адекватную реализацию __eq__(), могут быть заданы с помощью «PickleType(comparator=operator.eq)».
References: #560
Добавлен метод session.is_modified(obj); выполняет ту же операцию сравнения «истории», что и операция flush; установка include_collections=False дает тот же результат, который используется, когда flush определяет, выдавать или нет UPDATE для строки экземпляра.
Добавлен аргумент «schema» для Sequence; используется в Postgres /Oracle, когда последовательность расположена в альтернативной схеме. Реализует часть, должна быть исправлена.
Исправлено отражение пустой строки для перечислений mysql.
Изменен диалект MySQL для использования старого синтаксиса LIMIT <offset>, <limit> вместо LIMIT <l> OFFSET <o> для тех, кто использует версию 3.23.
References: #794
В relation() добавлен флаг „passive_deletes=»all»“, отключающий обнуление атрибутов внешних ключей при удалении родительского объекта.
В столбцах defaults и onupdates, выполняемых inline, будут добавлены скобки для подзапросов и других выражений, требующих скобок
Поведение типов String/Unicode, заключающееся в автоматическом преобразовании в TEXT/CLOB при отсутствии длины, теперь происходит только для точного типа String или Unicode без аргументов. Если вы используете VARCHAR или NCHAR (подклассы String/Unicode) без длины, то они будут интерпретироваться диалектом как VARCHAR/NCHAR; никакого «волшебного» преобразования при этом не происходит. Это менее удивительное поведение, и, в частности, оно помогает Oracle сохранять строковые параметры связывания как VARCHAR, а не CLOB.
References: #793
Исправления в ShardedSession для работы с отложенными колонками.
References: #771
Определяемая пользователем функция shard_chooser() должна принимать аргумент «clause=None», который является ClauseElement, передаваемым в session.execute(statement), и может быть использован для определения правильного идентификатора шарда (поскольку execute() не принимает экземпляр).
Скорректировано предшествование операторов NOT для соответствия „==“ и другим, так что ~(x <оператор> y) дает NOT (x <op> y), что лучше совместимо со старыми версиями MySQL. Это не относится к «~(x==y)», как в 0.3, поскольку ~(x==y) компилируется в «x != y», но все же относится к операторам типа BETWEEN.
References: #764
Другие билеты:,,,.
0.4.0beta5¶
no release dateИсправления пула соединений; сохраняется лучшая производительность бета4, но исправляется «переполнение соединения» и другие ошибки, которые присутствовали (например).
References: #754
Исправлены ошибки, связанные с определением правильных условий синхронизации из пользовательских условий наследования.
References: #769
Расширенное принуждение „engine_from_config“ для размера / переполнения пула QueuePool.
References: #763
mysql представления могут быть отражены снова.
References: #748
AssociationProxy теперь может принимать пользовательские геттеры и сеттеры.
Исправлена ошибка в работе запросов BETWEEN in orm.
Исправлена ковырялка OrderedProperties
References: #762
SQL-выражения по умолчанию и последовательности теперь выполняются «в линию» для всех столбцов, не являющихся первичными ключами, при INSERT или UPDATE, а также для всех столбцов при вызове в стиле executemany(). Флаг inline=True на любом операторе вставки/обновления также обеспечивает такое же поведение при выполнении одного execute(). result.postfetch_cols() представляет собой набор столбцов, для которых предыдущий единственный оператор вставки или обновления содержал SQL-выражение по умолчанию.
Исправлено поведение PG executemany().
References: #759
postgres отражает таблицы с autoincrement=False для столбцов первичного ключа, не имеющих значений по умолчанию.
postgres больше не оборачивает executemany() отдельными вызовами execute(), отдавая предпочтение производительности. Проверки «rowcount»/»concurrency» с удаленными элементами (которые используют executemany) отключены в PG, поскольку psycopg2 не сообщает правильное количество рядов для executemany().
References: #742
References: #748
References: #760
References: #762
References: #763
0.4.0beta4¶
Released: Wed Aug 22 2007postgres больше не оборачивает executemany() отдельными вызовами execute(), отдавая предпочтение производительности. Проверки «rowcount»/»concurrency» с удаленными элементами (которые используют executemany) отключены в PG, поскольку psycopg2 не сообщает правильное количество рядов для executemany().
“table“ и „column“ больше не импортируются. Они по-прежнему доступны по прямой ссылке (как в „sql.table“ и „sql.column“) или глобальным импортом из пакета sql. Слишком легко было случайно использовать sql.expressions.table вместо schema.Table, когда только начинаешь работать с SQLAlchemy, также как и column.
Внутренние классы, такие как ClauseElement, FromClause, NullTypeEngine и т.д., также больше не импортируются в ваше пространство имен
Имя совместимости „Smallinteger“ (маленькое i!) больше не импортируется, но пока остается в schema.py. SmallInteger (большое I!) по-прежнему импортируется.
Пул соединений использует внутреннюю стратегию «threadlocal» для возврата одного и того же соединения, уже привязанного к потоку, для «контекстных» соединений; это соединения, используемые при выполнении «без соединения», например insert().execute(). Это похоже на «частичную» версию стратегии движка «threadlocal», но без части потоково-локальных транзакций. Мы надеемся, что это позволит снизить накладные расходы на пул соединений, а также уменьшить использование базы данных. Однако если окажется, что это негативно сказывается на стабильности, мы откажемся от этой стратегии.
Исправление обработки параметров связывания таким образом, что значения «False» (например, пустые строки) по-прежнему обрабатываются/кодируются.
Исправлено «генеративное» поведение select(), в результате чего вызовы column(), select_from(), correlate() и with_prefix() не изменяют исходный объект select
References: #752
Добавлен адаптер «legacy» для типов, благодаря которому пользовательские классы TypeEngine и TypeDecorator, определяющие convert_bind_param() и/или convert_result_value(), будут продолжать работать. Также поддерживается вызов super() версии этих методов.
Добавлена функция session.prune(), обрезающая экземпляры, кэшированные в сессии, на которые больше нет ссылок в других местах. (Утилита для карт идентификации strong-ref).
Добавлен метод close() для транзакции Transaction. Завершает транзакцию с использованием отката, если это крайняя транзакция, в противном случае просто завершается, не затрагивая внешнюю транзакцию.
Транзакционные и нетранзакционные сессии лучше интегрируются с привязанным соединением; выполнение функции close() гарантирует, что транзакционное состояние соединения будет соответствовать тому, которое существовало на нем до привязки к сессии.
Модифицированные функции операторов SQL стали операторами уровня модуля, что позволило сделать SQL-выражения pickleable.
References: #735
Небольшая корректировка класса mapper.__init__ для обеспечения поведения Py2.6 object.__init__().
Исправлен аргумент „prefix“ для функции select()
Connection.begin() больше не принимает nested=True, теперь вся эта логика находится в begin_nested().
Исправления нового «динамического» загрузчика отношений, включающего каскады
References: #735
References: #752
0.4.0beta3¶
Released: Thu Aug 16 2007Оптимизация типов SQL:
Новые тесты производительности показывают, что комбинированный тест mass-insert/mass-select содержит на 68% меньше вызовов функций, чем тот же тест в версии 0.3.
Общее улучшение производительности при итерации набора результатов составляет около 10-20%.
В types.AbstractType методы convert_bind_param() и convert_result_value() перешли в разряд вызываемых методов bind_processor() и result_processor(). Если вызываемый метод не возвращается, то функция предварительной и последующей обработки не вызывается.
В base/sql/defaults добавлены хуки, оптимизирующие вызов процессоров bind param/result таким образом, чтобы минимизировать накладные расходы на вызов методов.
Добавлена поддержка сценариев executemany(), чтобы не срабатывала ненужная логика «id последней строки» и не происходило чрезмерного обхода параметров.
В mapper() добавлен аргумент „inherit_foreign_keys“.
Добавлена поддержка строковой передачи даты в sqlite.
References: #738
References: #739
References: #743
References: #744
0.4.0beta2¶
Released: Tue Aug 14 2007oracle¶
Автокоммит после LOAD DATA INFILE для mysql.
Добавлен простейший класс SessionExtension, позволяющий выполнять пользовательскую функциональность на границах flush(), commit() и rollback().
Добавлена функция engine_from_config() для помощи в создании_engine() из конфига в стиле .ini.
base_mapper() становится обычным атрибутом.
session.execute() и scalar() могут искать таблицу, с которой будет осуществляться связывание, используя заданный ClauseElement.
Сессия автоматически экстраполирует таблицы из мапперов с привязками, также используется base_mapper, чтобы иерархии наследования привязывались автоматически.
Перемещение обхода ClauseVisitor обратно в inlined non-recursive.
misc¶
0.4.0beta1¶
Released: Sun Aug 12 2007orm¶
Скорость! Наряду с недавним увеличением скорости работы ResultProxy, значительно уменьшилось общее количество вызовов функций при больших нагрузках.
test/perf/masseagerload.py сообщает, что 0.4 имеет наименьшее количество вызовов функций среди всех версий SA (0.1, 0.2 и 0.3).
Новый api и реализация класса collection_class. Коллекции теперь инструментируются через украшения, а не через проксирование. Теперь вы можете создавать коллекции, которые сами управляют своим членством, а экземпляр вашего класса будет напрямую отображаться на свойство relation. Изменения прозрачны для большинства пользователей.
References: #213
InstrumentedList (как это было раньше) удален, а свойства отношения больше не имеют методов „clear()“, „.data“ или каких-либо других дополнительных методов, помимо тех, которые предоставляются типом коллекции. Разумеется, вы можете добавить их в пользовательский класс.
__setitem__-подобные присваивания теперь вызывают события удаления для существующего значения, если таковое имеется.
dict-лики, используемые в качестве классов коллекций, больше не нуждаются в изменении семантики __iter__ - вместо этого по умолчанию используется itervalues(). Это изменение несовместимо с предыдущими версиями.
Подкласс dict для сопоставленной коллекции в большинстве случаев уже не нужен. Orm.collections предоставляет готовые реализации, которые осуществляют поиск объектов по заданному столбцу или пользовательской функции по вашему выбору.
Присваивание коллекции теперь требует совместимого типа - присваивание None для очистки коллекции или присваивание списка коллекции dict теперь будет вызывать ошибку аргумента.
AttributeExtension переместился в интерфейсы, а .delete стал .remove Сигнатура метода события также поменялась местами.
Серьезная переработка Query:
Все методы selectXXX устарели. Стандартными методами теперь являются генеративные методы: filter(), filter_by(), all(), one() и т.д. Утратившие актуальность методы занесены в документ с их новыми заменами.
Свойства уровня класса теперь можно использовать в качестве элементов запроса… больше никаких „.c.“! Вместо «Class.c.propname» теперь используется «Class.propname». Поддерживаются все операторы клаузы, а также операторы более высокого уровня, такие как Class.prop==<некоторый экземпляр> для скалярных атрибутов, Class.prop.contains(<некоторый экземпляр>) и Class.prop.any(<некоторое выражение>) для атрибутов на основе коллекций (все они также являются отрицаемыми). Табличные выражения столбцов, а также столбцы, устанавливаемые на сопоставленные классы через „c“, конечно же, остаются полностью доступными и могут быть свободно смешаны с новыми атрибутами.
References: #643
Удалена древняя возможность query.select_by_attributename().
Логика псевдонимов, используемая в eager loading, была обобщена таким образом, что она также добавляет полную автоматическую поддержку псевдонимов в Query. Больше нет необходимости создавать явный псевдоним для многократного присоединения к одним и тем же таблицам; даже для самореферентных отношений.
join() и outerjoin() принимают аргументы «aliased=True». Это приводит к тому, что их соединения будут построены на псевдотаблицах; последующие вызовы filter() и filter_by() будут транслировать все табличные выражения (да, реальные выражения, использующие исходную сопоставленную таблицу) в выражения псевдотаблицы на время действия join() (т.е. до тех пор, пока не будет вызвана reset_joinpoint() или другая join()).
join() и outerjoin() принимают аргументы «id=<somestring>». При использовании аргумента «aliased=True» на идентификатор можно ссылаться с помощью add_entity(cls, id=<somestring>), чтобы можно было выбрать объединенные экземпляры, даже если они принадлежат псевдониму.
join() и outerjoin() теперь работают с самореферентными отношениями! Используя параметр «aliased=True», можно объединить столько уровней, сколько необходимо, т.е. query.join([„children“, „children“], aliased=True); критерий фильтрации будет относиться к самой правой объединенной таблице
Добавлена функция query.populate_existing(), помечающая запрос на перезагрузку всех атрибутов и коллекций всех экземпляров, затронутых в запросе, включая сущности, загруженные с нетерпением.
References: #660
Добавлена функция eagerload_all(), позволяющая с помощью eagerload_all(„x.y.z“) задать ускоренную загрузку всех свойств по заданному пути.
Капитальный ремонт для сессии:
Новая функция, «конфигурирующая» сессию, называется «sessionmaker()». Однократная передача различных аргументов-ключей в эту функцию возвращает новый класс, который создает сессию по данному стереотипу.
SessionTransaction удалена из «публичного» API. Теперь вы можете вызывать begin()/ commit()/rollback() на самой сессии.
Сессия также поддерживает транзакции SAVEPOINT; вызовите begin_nested().
Сессия поддерживает двухфазную фиксацию при вертикальном или горизонтальном разделении (т.е. при использовании более чем одного движка). Используйте twophase=True.
Флаг сессии «transactional=True» создает сессию, которая при первом использовании всегда помещается в транзакцию. При выполнении commit(), rollback() или close() транзакция завершается, но при следующем использовании начинается снова.
Сессия поддерживает параметр «autoflush=True». При этом перед каждым запросом выполняется flush(). Если использовать эту функцию совместно с транзакционной, то можно просто сохранить()/обновить(), а затем выполнить запрос, и новые объекты уже будут там. Для удаления оставшихся изменений используйте commit() в конце (или flush(), если не транзакционный).
Новая функция scoped_session() заменяет SessionContext и assignmapper. Развивает концепцию «sessionmaker()» для создания класса, конструкция Session() которого возвращает потоково-локальную сессию. Или вызывать все методы Session как методы класса, т.е. Session.save(foo); Session.commit(). как в старые добрые времена «objectstore».
Добавлен новый аргумент «binds» в Session для поддержки настройки нескольких привязок с помощью функции sessionmaker().
Добавлен простейший класс SessionExtension, позволяющий выполнять пользовательскую функциональность на границах flush(), commit() и rollback().
Отношения()на основе запросов, доступные с помощью dynamic_loader(). Это записываемая коллекция (поддерживающая функции append() и remove()), которая также является живым объектом Query при обращении к нему для чтения. Идеально подходит для работы с очень большими коллекциями, когда требуется только частичная загрузка.
flush()-встроенные в строку выражения INSERT/UPDATE. Присвойте атрибуту экземпляра любое SQL-выражение, например «sometable.c.column + 1». При выполнении функции flush() картограф обнаруживает это выражение и встраивает его непосредственно в оператор INSERT или UPDATE; атрибут получает отложенное значение для экземпляра, поэтому при следующем обращении к нему он загружает новое значение.
Представлена простейшая система шардинга (горизонтального масштабирования). Эта система использует модифицированный Session, который может распределять операции чтения и записи между несколькими базами данных на основе пользовательских функций, определяющих «стратегию шардинга». Экземпляры и их зависимые элементы могут быть распределены и запрошены между несколькими базами данных на основе значений атрибутов, круговой выборки или любой другой системы, определяемой пользователем.
References: #618
Функция Eager loading была усовершенствована, чтобы обеспечить еще большее количество соединений в большем количестве мест. Теперь она работает на любой произвольной глубине в самореферентных и циклических структурах. При загрузке циклических структур следует указать в relation() значение «join_depth», указывающее, сколько раз таблица должна соединяться сама с собой; каждый уровень получает отдельный псевдоним таблицы. Сами имена псевдонимов генерируются во время компиляции с использованием простой схемы подсчета, что значительно облегчает восприятие, а также, конечно, полностью детерминировано.
References: #659
Добавлены свойства составного столбца. Это позволяет создавать тип, представленный более чем одним столбцом, при использовании ORM. Объекты нового типа полностью функциональны в выражениях запросов, сравнениях, предложениях query.get() и т.д. и ведут себя так, как будто они являются обычными одноколоночными скалярами… но это не так! Используйте функцию composite(cls, *columns) в дикте «properties» мэппера, и экземпляры cls будут созданы/привязаны к одному атрибуту, состоящему из значений, соответствующих *columns.
References: #211
Улучшена поддержка пользовательских атрибутов column_property() с коррелированными подзапросами, теперь они лучше работают при ускоренной загрузке.
Поведение при «схлопывании» первичного ключа; отображатель будет анализировать все столбцы в заданном селекте на предмет «эквивалентности» первичного ключа, то есть столбцов, которые эквивалентны через отношения внешних ключей или через явное условие inherit_condition. В основном для сценариев наследования объединенных таблиц, когда различные именованные столбцы PK в наследуемых таблицах должны «схлопываться» в однозначный (или с меньшим числом значений) первичный ключ. Исправляет такие ситуации, как.
References: #611
При наследовании по объединенной таблице столбцы первичных ключей всех наследуемых классов теперь будут формироваться только по корневой таблице объединения. Это означает, что каждая строка в корневой таблице будет относиться к одному экземпляру. Если по каким-то редким причинам это нежелательно, то явные настройки primary_key на отдельных картографах будут отменяться.
При использовании флагов «полиморфный» с объединенным или однотабличным наследованием все ключи идентификации генерируются по корневому классу иерархии наследования, что позволяет query.get() работать полиморфно, используя ту же семантику кэширования, что и неполиморфный get. Обратите внимание, что в настоящее время эта функция не работает с конкретным наследованием.
Загрузка вторичного наследования: полиморфные отображения могут быть построены без аргумента select_table. Наследующие отображения, таблицы которых не были представлены в первоначальной загрузке, будут сразу же выполнять второй SQL-запрос, один раз для каждого экземпляра (т.е. не очень эффективно для больших списков), чтобы загрузить оставшиеся столбцы.
Вторичная загрузка наследования также может перевести второй запрос в «отложенную» загрузку на уровне столбцов с помощью аргумента «polymorphic_fetch», который может быть установлен в значение „select“ или „deferred“
Теперь можно отображать на свойства отображателя только подмножество доступных выбираемых колонок, используя include_columns/exclude_columns.
References: #696
Добавлена опция undefer_group() MapperOption, устанавливающая загрузку набора «отложенных» столбцов, объединенных «группой», как «не отложенных».
Переписана логика «детерминированного имени псевдонима», чтобы она была частью слоя SQL, что позволяет получить гораздо более простые имена псевдонимов и меток, более соответствующие стилю Hibernate
sql¶
Скорость! Компиляция пунктов, а также механика конструкций SQL были значительно оптимизированы и упрощены, что позволило на 20-30% улучшить накладные расходы на построение/компиляцию операторов, составляющие 0,3.
Все аргументы с ключевым словом «type», такие как аргументы bindparam(), column(), Column() и func.<something>(), переименованы в «type_». Эти объекты по-прежнему называют свой атрибут «type» как «type».
параметр case_sensitive=(True|False) удален из элементов схемы, так как проверка этого состояния добавляла много лишних вызовов методов, и не было ни одной достойной причины, чтобы когда-либо устанавливать значение False. Имена таблиц и столбцов, написанные в нижнем регистре, будут рассматриваться как нечувствительные к регистру (да, мы учитываем и стиль UPPERCASE, принятый в Oracle).
extensions¶
proxyengine временно удален в ожидании реально работающей замены.
SelectResults был заменен на Query. SelectResults / SelectResultsExt по-прежнему существуют, но возвращают немного измененный объект Query для обратной совместимости. Метод join_to() из SelectResults больше не существует, необходимо использовать join().
mysql¶
Имена таблиц и столбцов, загружаемых через отражение, теперь имеют юникод.
Теперь поддерживаются все стандартные типы столбцов, включая SET.
Отражение в таблице теперь может быть выполнено всего за один обход.
Теперь поддерживаются sql-режимы ANSI и ANSI_QUOTES.
Индексы теперь отражаются.
oracle¶
Добавлена рудиментарная поддержка OUT-параметров; используйте sql.outparam(name, type) для установки OUT-параметра, подобно bindparam(); после выполнения значения доступны через словарь result.out_parameters.
References: #507
misc¶
Добавлена поддержка контекстного менеджера (с выпиской) для транзакций.
Добавлена поддержка двухфазного коммита, пока работает с mysql и postgres.
Добавлена реализация субтранзакции, использующая точки сохранения.
Добавлена поддержка точек сохранения.
Таблицы можно отражать из базы данных по очереди, не объявляя их заранее. MetaData(engine, reflect=True) загрузит все таблицы, имеющиеся в базе данных, или используйте metadata.reflect() для более тонкого контроля.
DynamicMetaData была переименована в ThreadLocalMetaData
Конструктор ThreadLocalMetaData теперь не принимает аргументов.
BoundMetaData была удалена - обычные MetaData эквивалентны
Типы Numeric и Float теперь имеют флаг «asdecimal»; по умолчанию для Numeric он равен True, для Float - False. При значении True значения возвращаются как объекты decimal.Decimal, при значении False - как float(). Установки по умолчанию True/False уже используются в модулях PG и MySQL DBAPI.
References: #646
Новая реализация операторов SQL, которая удаляет все жестко закодированные операторы из структур выражений и переносит их в компиляцию; позволяет более гибко подходить к компиляции операторов; например, «+» компилируется в «||» при использовании в строковом контексте, или «concat(a,b)» в MySQL, тогда как в числовом контексте компилируется в «+». Исправления.
References: #475
»Анонимные» имена псевдонимов и меток теперь генерируются во время компиляции SQL полностью детерминированным образом… больше никаких случайных шестнадцатеричных идентификаторов
Значительно переработана архитектура элементов SQL (ClauseElement). Все элементы имеют общий фреймворк «мутабельности», который позволяет согласованно подходить к модификации элементов на месте, а также к генеративному поведению. Повышена стабильность работы ORM, в котором активно используются мутации SQL-выражений.
Методы select() и union() теперь имеют «генеративное» поведение. Такие методы, как order_by() и group_by(), возвращают новый экземпляр - исходный экземпляр остается неизменным. Негенеративные методы также остались.
Внутреннее устройство select/union значительно упрощено - все решения о «подзапросе» и «корреляции» вынесены на этап генерации SQL. Элементы select() теперь никогда не мутируют под действием вложенных в них контейнеров или в процессе компиляции любого диалекта
Аргумент select(scalar=True) устарел; используйте select(…).as_scalar(). Полученный объект полностью подчиняется интерфейсу «столбца» и лучше работает в выражениях.
Добавлена функция select().with_prefix(„foo“), позволяющая поместить любой набор ключевых слов перед предложением columns в SELECT
References: #504
Добавлена поддержка срезов массива в row[<index>].
References: #686
Наборы результатов делают лучшую попытку сопоставить типы DBAPI, присутствующие в cursor.description, с объектами TypeEngine, определенными диалектом, которые затем используются для обработки результатов. Заметим, что это действует только для текстового SQL; построенные SQL-операторы всегда имеют явную карту типов.
Наборы результатов CRUD-операций немедленно закрывают курсор, лежащий в их основе, а также автоматически закрывают соединение, если оно определено для данной операции; это позволяет более эффективно использовать соединения для последовательных CRUD-операций с меньшей вероятностью «болтающихся соединений».
Умолчания столбцов и Python-функции onupdate (т.е. передаваемые в ColumnDefault) могут принимать ноль или один аргумент; один аргумент - это ExecutionContext, из которого можно вызвать «context.parameters[someparam]» для доступа к другим значениям параметров связывания, привязанным к утверждению. Также доступно соединение, используемое для выполнения, что позволяет предварительно выполнять операторы.
References: #559
Добавлена поддержка «явного» создания/отбрасывания/исполнения последовательностей (т.е. каждому из этих методов в Sequence можно передать «connectable»).
Улучшено цитирование идентификаторов при работе со схемами.
Стандартизировано поведение при отражении таблиц, в которых типы не могут быть найдены; вместо них подставляется NullType, выдается предупреждение.
ColumnCollection (т.е. атрибут „c“ в таблицах) соответствует словарной семантике для «__contains__».
References: #606
Скорость! Механика обработки результатов и параметров связывания была переработана, оптимизирована и оптимизирована таким образом, чтобы выполнять как можно меньше вызовов методов. Контрольные тесты массового INSERT и массовой итерации набора строк показали, что 0.4 работает более чем в два раза быстрее, чем 0.3, используя на 68% меньше вызовов функций.
Теперь можно подключиться к жизненному циклу пула и выполнять SQL-запросы или другую логику при каждом новом соединении DBAPI, выходе и входе в пул.
Соединения получают коллекцию .properties, содержимое которой привязано к времени жизни базового соединения DBAPI
Удалены аргументы auto_close_cursors и disallow_open_cursors из Pool; уменьшены накладные расходы, так как курсоры обычно закрываются ResultProxy и Connection.
Добавлен тип данных PGArray для использования типов данных массивов postgres.