От какого базового класса наследуются модели в SQLAlchemy?

Ответ

В SQLAlchemy ORM модели наследуются от специального базового класса, который создается с помощью декларативного подхода. Этот базовый класс связывает Python-класс с таблицей в базе данных и наделяет его функциональностью ORM (Object-Relational Mapping).

Существует два распространенных способа его создания:

1. Классический подход (до SQLAlchemy 1.4): Используется функция declarative_base().

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

# Создание базового класса для моделей
Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))

2. Современный подход (SQLAlchemy 1.4+): Используется класс DeclarativeBase.

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import DeclarativeBase

# Создание базового класса для моделей
class Base(DeclarativeBase):
    pass

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))

В обоих случаях Base служит центральной точкой, через которую SQLAlchemy отслеживает все сопоставленные классы (модели).

Ответ 18+ 🔞

А, ну это ж классика, блядь! Сидишь такой, пишешь на питоне, и тут бац — нужно с базой данных работать. А руками SQL писать — это ж пиздец какой-то, скука смертная. Ну и придумали эту ORM, чтобы жизнь малиной не казалась.

Так вот, смотри. В SQLAlchemy, если ты хочешь сделать из своего питонячего класса полноценную модель для таблицы в базе, тебе нужно этот класс куда-то пристроить. Не просто так же он будет висеть, как манда с ушами. Его нужно наследовать от специального базового класса, который и является тем самым клеем между твоим кодом и этой самой базой данных.

И способов его создать — овердохуища, но основных два. Один — старый, как говно мамонта, но ещё живой. Второй — новый, модный, молодёжный.

Первый, классический, для дедов, которые помнят SQLAlchemy 1.3 Тут всё просто, как три копейки. Берёшь функцию declarative_base(), вызываешь её, и она тебе выплёвывает этот самый базовый класс. Всё, приехали.

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

# Вот тут магия и происходит. Получаем базовый класс.
Base = declarative_base()

# А теперь делаем от него наследничка. Это и будет наша модель.
class User(Base):
    __tablename__ = 'users' # Это обязательно, блядь! Иначе SQLAlchemy офигеет и не поймёт, куда эту хрень в базе пихать.

    id = Column(Integer, primary_key=True) # Ну, а это уже поля таблицы. Привыкай.
    name = Column(String(50))

Второй, современный, для хипстеров с SQLAlchemy 1.4 и выше Тут уже не функция, а нормальный класс DeclarativeBase. От него просто наследуешься и создаёшь свой базовый класс. Чуть более явно, что ли.

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import DeclarativeBase

# Создаём свой базовый класс. Можно даже что-то своё туда добавить, если фантазия есть.
class Base(DeclarativeBase):
    pass # А можно и не pass, но обычно так.

# И опять же, делаем от него наследничка. Суть та же.
class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))

И в том, и в другом случае, этот твой Base — он как пастух для овец. Все модели, которые от него наследуются, он знает в лицо. И когда придёт время создавать таблицы в базе (Base.metadata.create_all(engine)), он всех этих User-ов, Product-ов и прочих Order-ов соберёт в кучу и скажет базе: «Вот, сука, делай таблицы под них!». Удобно, ёпта. А то самому за каждым классом бегать — волнение ебать, да и терпения ноль.