⚖️ Старый vs Новый: SQLAlchemy 1.x (лекция) и 2.x
⚡ Кратко
- Лекция (1.x):
declarative_base(),Column(Integer, ...),sessionmaker(bind=engine) - Современно (2.x):
class Base(DeclarativeBase),Mapped[int] = mapped_column(...),with Session(engine) as session: - Главное преимущество 2.x: статические аннотации типов — IDE знает типы полей, ошибки видны до запуска.
- В интернете много кода на 1.x — при копировании проверяйте версию.
⚠️ Внимание: код в левой колонке — это синтаксис лекции (SQLAlchemy 1.x). Именно так написан учебный материал. Правая колонка показывает тот же код на современном API 2.x. В реальных проектах используйте 2.x.
1. Базовый класс
🔥 Как в лекции (SQLAlchemy 1.x)
# Из лекции — устаревший синтаксис
from sqlalchemy.orm import sessionmaker, declarative_base
Base = declarative_base() # функция, не наследование
✨ Современно (SQLAlchemy 2.x)
# Современный синтаксис
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
pass # наследование от класса
2. Объявление полей модели
🔥 Как в лекции (SQLAlchemy 1.x)
# Модель User из лекции (1.x)
from sqlalchemy import Column, Integer, String
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True) # без аннотаций
name = Column(String(30))
age = Column(Integer)
- ❌ Нет аннотаций типов — IDE не знает, что
user.nameэто строка - ❌ Mypy/pyright не проверяют типы полей
✨ Современно (SQLAlchemy 2.x)
# Та же модель User на 2.x
from sqlalchemy import String, Integer
from sqlalchemy.orm import Mapped, mapped_column
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(30))
age: Mapped[int] = mapped_column(Integer)
- ✅ Аннотации типов — IDE знает точный тип каждого поля
- ✅ Работает с Mypy, Pyright, Pylance
- ✅
Mapped[тип | None]явно показывает необязательные поля
3. Создание сессии
🔥 Как в лекции (SQLAlchemy 1.x)
# Из лекции: sessionmaker + ручное создание экземпляра
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine) # bind= устарело
session = Session()
session.add(new_user)
session.commit()
session.close() # нужно закрывать вручную!
✨ Современно (SQLAlchemy 2.x)
# Контекстный менеджер — закрытие автоматическое
from sqlalchemy.orm import Session
with Session(engine) as session:
session.add(new_user)
session.commit()
# Сессия закрывается автоматически при выходе из with-блока
4. Полный пример (лекция 1.x → современный 2.x)
🔥 Полный код из лекции (1.x)
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker, declarative_base
Base = declarative_base()
engine = create_engine('sqlite:///example.db')
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(30))
age = Column(Integer)
Session = sessionmaker(bind=engine)
session = Session()
Base.metadata.create_all(engine)
new_user = User(name='John Doe', age=30)
session.add(new_user)
session.commit()
✨ Тот же код на SQLAlchemy 2.x
from sqlalchemy import create_engine, String, Integer
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
engine = create_engine('sqlite:///example.db')
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(30))
age: Mapped[int] = mapped_column(Integer)
Base.metadata.create_all(engine)
with Session(engine) as session:
new_user = User(name='John Doe', age=30)
session.add(new_user)
session.commit()
Таблица отличий
| Возможность | SQLAlchemy 1.x (как в лекции) | SQLAlchemy 2.x (актуально) |
|---|---|---|
| Базовый класс | declarative_base() |
class Base(DeclarativeBase) |
| Поля модели | Column(Integer, ...) |
Mapped[int] = mapped_column(...) |
| Создание сессии | sessionmaker(bind=engine) + Session() |
with Session(engine) as session: |
| Импорт базы | from sqlalchemy.orm import declarative_base |
from sqlalchemy.orm import DeclarativeBase |
| Типизация полей | Нет статических аннотаций | Полная поддержка Mapped[тип] |
| Закрытие сессии | Вручную: session.close() |
Автоматически через контекстный менеджер |
Важно: в интернете огромное количество примеров написано на SQLAlchemy 1.x. Если вы видите
declarative_base() или sessionmaker(bind=engine) — это старая версия. В нашем курсе основные файлы (examples, tasks, solutions, homework) используют SQLAlchemy 2.x.