Engine, Session и база SQLite
Уроки курсаEngine, Session и база SQLite
В прошлом уроке мы описали модель Room через DeclarativeBase и получили класс, который SQLAlchemy умеет превращать в таблицу. Но саму таблицу мы ещё не создали — для этого нужен Engine, указывающий на конкретный файл базы данных.
Engine и metadata.create_all: подключение к SQLite и создание таблиц
Engine — это точка входа SQLAlchemy к базе данных. Его создают один раз для всего приложения:
from sqlalchemy import create_engine
from models import Base
DATABASE_URL = "sqlite:///./roomly.db"
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
URL sqlite:///./roomly.db означает файловую базу SQLite. Три слеша — это протокол плюс путь; точка-слеш делает путь относительным. Важный момент: ./ отсчитывается от рабочего каталога, в котором вы запускаете uvicorn, а не от расположения файла database.py. Если запустить uvicorn из другого каталога, файл roomly.db окажется там же.
connect_args={"check_same_thread": False} — в SQLAlchemy 2.0.36 это значение уже выставлено по умолчанию для файловой SQLite. Явная передача аргумента не исправляет ошибку, а документирует сделанный выбор: при чтении кода сразу видно, что параметр проверен и сознательно установлен. Этот аргумент не означает, что одну сессию безопасно использовать в нескольких потоках одновременно — об этом ниже.
create_engine не открывает соединение в момент вызова. Движок создаётся мгновенно; реальное обращение к файлу произойдёт при первой операции с базой, например при create_all.
Создание таблиц при импорте
Когда database.py импортируется, Python исполняет строку:
Base.metadata.create_all(bind=engine)
К этому моменту from models import Base уже выполнил весь models.py — в том числе объявление класса Room. Поэтому metadata знает о таблице rooms и создаст её в файле roomly.db, если она там ещё не существует.
Повторный вызов create_all — при следующем перезапуске приложения — безопасен: существующую таблицу он пропустит, данные в ней не тронет. Однако если вы добавили новый столбец в модель Room, create_all его не добавит в уже созданную таблицу. Для изменения схемы существующей базы нужны инструменты миграций — это отдельная тема.
