SQLAlchemy

Один из самых популярных пакетов для работы с базами данных — sqlalchemyarrow-up-right. Он позволяет конструировать запросы для различных баз данных. Рассмотрим основные практические моменты в работе с sqlalchemy.

alembicarrow-up-right — пакет для миграций

Описание схемы базы данных

Базовый пример

from sqlalchemy import Column, ForeignKey, String, Integer, Boolean, Table
from sqlalchemy.orm import declarative_base

from table_base import Base
from myrelationship import MyRelationship


Base = declarative_base()


class TableA(Base):
    __tablename__ = "table_a"

    key = Column(String(40), primary_key=True)
    value = Column(Integer, ForeighKey('table_b.id'))
    b = Column(Boolean)

Base — это базовый класс, который будет хранить всю информацию о вашей будущей схеме базы. При этом, он должен быть определен только один раз. Все другие таблицы, должны наследоваться от Base.

Declarative vs. Imperative Formsarrow-up-right

Declarative Form with mapping (это новый подход, лучше использовать его!)

Declarative Form without mapping (это по классике):

List and sets

По умолчанию, связи маппятся в List. Но можно сделать в Set:

Imperative Form:

У нас есть две таблицы, описанные декларативно. Добавляем связь императивно:

Организация кода для описания таблиц

Один из возможных способов организации кода для описания схемы базы:

Relationships

One-to-One

На базовом уровне это выглядит следующим образом. То есть, мы отключаем поддержку коллекций и тем самым добиваемся One-to-One отношения. Это нужно, когда у родителя может быть только один ребенок, а у ребенка — один родитель.

One-to-Many

На базовом уровне это выглядит следующим образом

Для двунаправленной связи, чтобы Child видел Parent целиком, а не только id (далее не надо будет делать отдельный запрос на уровне кода), изменим Child и Parent следующим образом:

Many-to-One

На базовом уровне это выглядит следующим образом

Для двунаправленной связи, чтобы из Child можно было получить всех родителей, поменяем Parent и Child следующим образом

Many-to-Many

На базовом уровне это выглядит следующим образом.

Мы создаем ассоциативную таблицу, которая хранит все уникальные пары ключей из обоих таблиц и подключаем ее через свойство secondary. Через свойство back_populates настраиваем связь.

Если нам надо добавить в ассоциацию доп поля, или мы хотим чтобы все было в одном стиле, можем создать обычную таблицу как Child и Parent: https://docs.sqlalchemy.org/en/14/orm/basic_relationships.html#association-objectarrow-up-right

Конструирование запросов

Конструирование запросов к обычной таблице

Работа с relationships

Паттерн Provider -> Repository -> Database

Есть популярный паттерн организации кода при работе с базой (из джавы, на сколько его правильно применять в Python — хз, но так понятнее что происходит). Суть в отделении бизнес-логики (это Provider), CRUD-операций (это Repository) и работы с базой (это Database).

Пример:

database.py

repository.py

provider.py

Подсоединяемся к базе

Transactions

Выполнение делаем через SQLAlchemy используя транзакции (Session): https://habr.com/ru/articles/597999/arrow-up-right

databases

Выполнение запросов к базе делаем через пакет databases. Только схему базы в бд создаем через sqlalchemy (из объекта Base).

Last updated