Ошибка 1: Забыли create_all — таблица не создана
Симптом:
OperationalError: (sqlite3.OperationalError) no such table: users
# Неверно — пропущен create_all
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:
session.add(User(name='John Doe', age=30))
session.commit() # OperationalError: no such table: users
# Верно — сначала создаём таблицы, потом открываем сессию
Base.metadata.create_all(engine) # ОБЯЗАТЕЛЬНО!
with Session(engine) as session:
session.add(User(name='John Doe', age=30))
session.commit() # теперь работает
Ошибка 2: Нет commit — данные не сохраняются
# Неверно — забыли commit
with Session(engine) as session:
user = User(name='Alice', age=25)
session.add(user)
# session.commit() ← пропущено!
# При выходе из with-блока сессия выполняет rollback
# Данные НЕ сохранились в БД!
# Верно
with Session(engine) as session:
user = User(name='Alice', age=25)
session.add(user)
session.commit() # ОБЯЗАТЕЛЬНО для сохранения
print(f'Сохранён пользователь id={user.id}')
Ошибка 3: DetachedInstanceError — обращение к объекту вне сессии
Симптом:
DetachedInstanceError: Instance <User at 0x...> is not bound to a Session
После закрытия сессии объекты переходят в состояние Detached — они остаются в памяти, но отсоединены от БД. Обращение к атрибутам, которые не были загружены, вызывает ошибку.
# Неверно — обращение к объекту после закрытия сессии
with Session(engine) as session:
user = session.get(User, 1)
# Сессия закрыта — user в состоянии Detached
print(user.name) # это работает (значение уже загружено)
# Но если есть lazy-загружаемые связи:
# print(user.orders) # DetachedInstanceError!
# Верно — получить все нужные данные внутри сессии
with Session(engine) as session:
user = session.get(User, 1)
user_name = user.name # сохраняем значение внутри сессии
print(user_name) # OK — это строка, не ORM-объект
Контрольный вопрос из лекции: что происходит с объектами после
session.close()? Объекты остаются в памяти, но отсоединяются от базы данных (состояние Detached).
Ошибка 4: Неверная строка подключения / нет драйвера
Симптом:
ModuleNotFoundError: No module named 'pymysql' или NoSuchModuleError
# Неверно — используется MySQL, но pymysql не установлен
engine = create_engine('mysql+pymysql://user:password@localhost:3306/mydb')
# ModuleNotFoundError: No module named 'pymysql'
# Верно — сначала установить драйвер
# pip install pymysql
engine = create_engine('mysql+pymysql://user:password@localhost:3306/mydb')
Для SQLite драйвер не нужен — он встроен в Python:
# SQLite не требует дополнительных библиотек
engine = create_engine('sqlite:///:memory:') # всегда работает
Ошибка 5: Сессия не закрыта — утечка соединений
# Неверно — ручное управление без гарантии закрытия
session = Session(engine)
user = User(name='Bob', age=30)
session.add(user)
session.commit()
# Если здесь возникнет исключение — session.close() не вызовется!
session.close() # может не выполниться
# Верно — контекстный менеджер гарантирует закрытие
with Session(engine) as session:
user = User(name='Bob', age=30)
session.add(user)
session.commit()
# session.close() вызывается автоматически при любом выходе из блока