← Назад к вопросам

От чего наследуешь модель при ее создании в SQLAlchemy?

2.2 Middle🔥 181 комментариев
#Базы данных (SQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

От чего наследуешь модель при её создании в SQLAlchemy

При создании модели в SQLAlchemy нужно наследоваться от декларативного базового класса (Base), который связывает Python класс с таблицей в БД.

Основной подход: Declarative Base

from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.orm import declarative_base, sessionmaker
from datetime import datetime

# Создаём базовый класс для всех моделей
Base = declarative_base()

# Все модели наследуются от Base
class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True)
    name = Column(String(100), nullable=False)
    email = Column(String(255), unique=True)
    created_at = Column(DateTime, default=datetime.utcnow)

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

Зачем наследуться от Base

  1. Регистрация в реестре — SQLAlchemy узнает о классе и его схеме
  2. Автоматическое создание таблиц — Base.metadata.create_all(engine)
  3. ORM функционал — получаете методы для запросов и сессий
  4. Интеграция с миграциями — Alembic использует Base.metadata
  5. Relationship и Foreign Keys — работают корректно только с моделями из одного Base

Правильный паттерн: Отдельный модуль Base

В production проектах Base создаётся один раз в отдельном модуле:

# models/base.py
from sqlalchemy.orm import declarative_base

Base = declarative_base()
# models/user.py
from sqlalchemy import Column, Integer, String, DateTime
from datetime import datetime
from models.base import Base

class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True)
    name = Column(String(100))
    created_at = Column(DateTime, default=datetime.utcnow)
# models/__init__.py
from models.base import Base
from models.user import User
from models.post import Post

# Все модели импортируются здесь для использования в миграциях
__all__ = ["Base", "User", "Post"]

Современный подход: registry

В SQLAlchemy 1.4+ можно использовать registry для большей гибкости:

from sqlalchemy.orm import registry

reg = registry()
Base = reg.generate_base()

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)

Множественные Base классы

ВАЖНО: Не используйте несколько Base классов в одном проекте!

# Плохо — разные регистры, migrations не сработают
Base1 = declarative_base()
Base2 = declarative_base()

class User(Base1):
    __tablename__ = "users"

class Post(Base2):
    __tablename__ = "posts"
# Хорошо — один Base для всего проекта
Base = declarative_base()

class User(Base):
    __tablename__ = "users"

class Post(Base):
    __tablename__ = "posts"

Использование с Goose миграциями

При работе с Goose (raw SQL) Base всё ещё используется для ORM и типизации:

# models.py — используется только для ORM
from sqlalchemy.orm import declarative_base
from sqlalchemy import Column, Integer, String

Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    name = Column(String(100))
-- migrations/0001_create_users.sql
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

Goose создаёт таблицы, SQLAlchemy модели используют их для ORM.

Проверка наследования

from sqlalchemy.orm import class_mapper
from sqlalchemy.exc import InvalidRequestError

# Проверить, является ли класс моделью
if isinstance(User, type) and hasattr(User, "__tablename__"):
    print("User — валидная модель")

# Получить информацию о колонках
for column in User.__table__.columns:
    print(f"{column.name}: {column.type}")

Общие ошибки

  1. Забывают создать Base — затем ничего не работает
  2. Наследуют от объекта прямо — теряют ORM функционал
  3. Используют несколько Base — миграции путаются
  4. Забывают импортировать модели — в init.py или config

Лучшие практики

  • Один Base на весь проект в модуле models/base.py
  • Все модели наследуются от одного Base
  • Импортируйте все модели в init.py перед использованием в миграциях
  • Используйте tablename явно для каждой модели
  • Типизируйте relationships и foreign keys через type hints

Это фундамент для корректной работы ORM и миграций в SQLAlchemy.