← Назад к вопросам
От чего наследуешь модель при ее создании в 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
- Регистрация в реестре — SQLAlchemy узнает о классе и его схеме
- Автоматическое создание таблиц — Base.metadata.create_all(engine)
- ORM функционал — получаете методы для запросов и сессий
- Интеграция с миграциями — Alembic использует Base.metadata
- 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}")
Общие ошибки
- Забывают создать Base — затем ничего не работает
- Наследуют от объекта прямо — теряют ORM функционал
- Используют несколько Base — миграции путаются
- Забывают импортировать модели — в init.py или config
Лучшие практики
- Один Base на весь проект в модуле models/base.py
- Все модели наследуются от одного Base
- Импортируйте все модели в init.py перед использованием в миграциях
- Используйте tablename явно для каждой модели
- Типизируйте relationships и foreign keys через type hints
Это фундамент для корректной работы ORM и миграций в SQLAlchemy.