Автостопом по Python.

SQLAlchemy.

SQLAlchemy (http://www.sqlalchemy.org/) — очень популярный тулкит для баз данных. Django имеет возможность переключиться с собственного ORM на SQLAchemy. Это бэкенд для мегаруководства для Flask по созданию собственного блога (http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world). Pandas использует его как SQL (http://bit.ly/pandas-sql-query).

SQLAlchemy — это единственная из перечисленных здесь библиотек, следующая шаблону Data Mapper (http://martinfowler.com/eaaCatalog/dataMapper.html) Мартина Фаулера (Martin Fowler) (вместо более популярного шаблона Active Record, http://martinfowler.com/eaaCatalog/activeRecord.html). В отличие от остальных библиотек, SQLAlchemy предоставляет не только уровень ORM, но и обобщенный API (который называется уровнем Core), предназначенный для написания кода без SQL. Слой ORM находится выше уровня Core, использующего объекты, которые непосредственно соотносятся с лежащей в его основе базой данных. Пользователь должен явно соотносить эти объекты и ORM, поэтому для начала работы потребуется написать больше кода (это может быть сложно для тех, кто только приступил к работе с реляционными базами данных — создавать объекты можно только явно).

SQLAlchemy может работать на Jython и PyPy и поддерживает версии Python от 2.5 до самой свежей. В следующих фрагментах кода показано, что нужно сделать, чтобы создать объекты с отношением «многие-ко-многим». Мы создадим три объекта на уровне ORM: Customer (Покупатель), Cheese (Сыр) и Purchase (Покупка). Один покупатель может сделать много покупок (отношение «многие-к-одному»), а в одной покупке может содержаться множество видов сыра (отношение «многие-ко-многим»). Мы приводим этот пример для того, чтобы показать несоотнесенную таблицу purchases_cheeses (ей не нужно находиться в ORM, поскольку она нужна только для связи между видами сыра и покупками).

Другие ORM создали бы эту таблицу за кулисами — в этом заключается одно из самых заметных различий между SQLAlchemy и другими библиотеками:

Автостопом по Python. Автостопом по Python.

Автостопом по Python.Декларативный базовый объект — это метакласс[121], который перехватывает создание каждой таблицы из ORM и определяет соответствующую таблицу на уровне Core.

Автостопом по Python.Объекты на уровне ORM наследуют от декларативного базового объекта.

Автостопом по Python.Это несоотнесенная таблица на слое Core; это не класс, он не наследуется у декларативного базового объекта, соответствует таблице purchases_cheeses в базе данных и нужен для того, чтобы предоставить соотношение «многие-ко-многим» между сырами и идентификаторами покупок.

Автостопом по Python.Сравните ее с соотнесенной таблицей Cheese на уровне ORM. За кулисами таблица Cheese.__table__ создается на основном слое. Она будет соответствовать таблице базы данных cheeses.

Автостопом по Python.Это отношение явно показывает отношение между соотнесенными классами Cheese и Purchase: они связаны друг с другом опосредованно с помощью вторичной таблицы purchases_cheeses (в противоположность непосредственному связыванию с помощью ForeignKey).

Автостопом по Python.Back_populates добавляет слушателя событий, поэтому при добавлении нового объекта типа Purchase в Cheese.purchases объект типа Cheese также появится в Purchase.cheeses.

Автостопом по Python.Этот фрагмент — вторая половина реализации отношения «многие-ко-многим».

Таблицы явно созданы с помощью декларативного базового объекта:

From sqlalchemy import create_engine.

Engine = create_engine('sqlite://').

Base.metadata.create_all(engine).

А теперь взаимодействие, при котором используются объекты слоя ORM, выглядит так же, как и для других библиотек, имеющих ORM:

Автостопом по Python.

Автостопом по Python.Вы должны явно вызывать метод commit() для отправки изменений в базу данных.

Автостопом по Python.Объекты, состоящие в отношениях «многие-ко-многим», не добавляются во время создания (их необходимо вручную вносить уже после создания).

Рассмотрим несколько примеров запросов:

Автостопом по Python. Автостопом по Python.

Автостопом по Python.Так создается отношение «многие-ко-многим» для таблицы purchases_cheeses, которая не соотносится с высокоуровневым объектом ORM.

Автостопом по Python.Этот запрос считает количество покупок каждого вида сыра.

Для того чтобы узнать больше, обратитесь к документации SQLAlchemy (http://docs.sqlalchemy.org/en/rel_1_0/).