Асинхронная SQLAlchemy 2.0 является новой версией одной из самых популярных библиотек для работы с базами данных в Python. Она предлагает улучшенное асинхронное API для выполнения запросов к базам данных и работает с асинхронными фреймворками, такими как FastAPI.
В этом руководстве мы рассмотрим использование асинхронной SQLAlchemy 2.0 с alembic миграциями и отношениями между таблицами. Мы также обсудим, как создавать модели таблиц и выполнять запросы к базе данных, а также как настроить среду разработки для работы с этими инструментами.
- Установка библиотек
Для начала вам понадобится установить необходимые библиотеки. Для установки SQLAlchemy 2.0 и alembic выполните следующие команды:
pip install sqlalchemy sqlalchemy-async alembic
- Настройка бд
Далее вам необходимо настроить подключение к вашей базе данных. Для этого создайте файл config.py и добавьте в него следующий код:
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import declarative_base, sessionmaker
DATABASE_URL = "postgresql+asyncpg://user:password@localhost/db_name"
engine = create_async_engine(DATABASE_URL, echo=True)
Base = declarative_base()
async_session = sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)
Замените значения user, password, localhost и db_name на соответствующие значения вашей базы данных.
- Создание моделей таблиц
Теперь создайте файл models.py и определите в нем модели таблиц. В примере ниже мы создадим модели для таблицы Users и Posts.
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from config import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
email = Column(String, unique=True)
posts = relationship("Post", back_populates="author")
class Post(Base):
__tablename__ = "posts"
id = Column(Integer, primary_key=True, index=True)
title = Column(String)
content = Column(String)
author_id = Column(Integer, ForeignKey("users.id"))
author = relationship("User", back_populates="posts")
- Создание миграций
Теперь давайте создадим миграции для наших моделей. Для этого выполните следующие команды:
alembic init alembic
Затем настройте файл alembic.ini, добавив путь к вашей базе данных в переменную sqlalchemy.url.
sqlalchemy.url = postgresql+asyncpg://user:password@localhost/db_name
Создайте миграцию:
alembic revision --autogenerate -m "initial migration"
alembic upgrade head
- Выполнение запросов к базе данных
Теперь мы можем выполнять запросы к базе данных с использованием асинхронной SQLAlchemy. Для этого создадим файл crud.py и добавим в него следующий код:
from sqlalchemy.ext.asyncio import AsyncSession
from models import User, Post
from config import async_session
async def create_user(user_data):
async with async_session() as session:
user = User(**user_data)
session.add(user)
await session.commit()
return user
async def get_users():
async with async_session() as session:
return await session.execute(User.select()).scalars().all()
- Настройка среды разработки
Для того чтобы работать с асинхронной SQLAlchemy 2.0 в вашем проекте FastAPI, необходимо добавить пул подключений к базе данных в зависимости FastAPI.
from fastapi import FastAPI
from sqlalchemy.ext.asyncio import AsyncSession
app = FastAPI()
@app.middleware("http")
async def db_session_middleware(request, call_next):
request.state.db = AsyncSession()
response = await call_next(request)
await request.state.db.close()
return response
Теперь вы можете использовать асинхронную SQLAlchemy 2.0 в ваших FastAPI приложениях для работы с базами данных. Надеюсь, этот гайд был полезен для вас!
Видеоурок по данной теме можно посмотреть по ссылке: ссылка на видео
Таймкоды:
Alembic:
0:10 Введение в Alembic
1:35 Установка Alembic
1:55 Настройка Alembic
48:01 Исправление для настройки подключения к ДБ
8:35 Создание первой миграции
14:24 Выполнение и откат миграций
40:22 Слежение за версиями миграций
Создание моделей:
18:00 Создание User
44:52 Добавление строкового представления
21:18 Создание Post
22:00 – Значения по умолчанию
23:02 – Создание внешнего ключа
25:51 Добавление связей между моделями (relationship) "один ко многим" и использование TYPE_CHECKING
29:42 Создание Profile, добавление связей "один к одному"
31:48 Использование Mixin (с использованием declared_attr) для избежания дублирования кода.
CRUD:
42:52 create_User
46:18 рефакторинг Config.py
48:17 get_User (два варинта)
51:43 create_Profile
54:10 show_Users_with_Profiles
55:44 Использование option(JoinedLoad())
58:10 create_Post
1:01:18 get_Users_with_Posts
1:02:41 Использование Unique и option(SelectInLoad())
1:06:27 get_Post_with_Users
1:08:24 get_User_with_Posts_and_Profile
1:10:22 get _Profile_with_User_and_Posts – вложенные и комбинированные join() (для подгрузки данных и фильтрации )
1:13:31 – ИТОГИ
PS опции joinedload() используем для отношения "один к одному", а selectinload() для отношения "один ко многим"
Сурен подскажи пожалуйста, почему ты используешь в крудах core алхимию, а не до конца используешь декларативные методы, например, session.query(User).filter_by(username=username). Есть какой то профит или привычка?
Казалось бы, те же самые 15 минут на объяснение алембик, но без воды и на понятном языке (спокойно все применил в своем проекте). Благодарю.
Спасибо огромное за видео! Очень много полезной и хорошо структурирвоанной информации. Хотел бы добавить насчёт аннотации полей в sqlalchemy, что, если мне не изменяет память, можно либо модель указать в кавычках а ля post: Mapped["Post"], либо использовать if TYPE_CHECKING, но не обязательно все сразу, это два разных способа избежать circular imports, не обязательно оба одновременно использовать
Превосходная подача материала! Всё подробно и в то же время ничего лишнего. Преподавать ваше призвание! Спасибо за курс.
спасибо!
Это великолепно! Вы отлично объясняете. Огромное спасибо за труды!
Это легендарно, Сурен. Спасибо!
У меня не получилось изменить схему базы данных и создавать миграции.
как это сделать?
Смотрю уже пару дней. Пока это видео оказалось самым тяжелым, но не менее информативным и познавательным. Спасибо за контент!
Добрый день а как настроить для alembic схему по умолчанию что бы он там проверял таблици и при наличии в миграциях прописывал апгрейды, а то в постгресе он всё время пытается в паблик схеме всё делать
Видео просто супер полезное, спасибо огромное!
Это было сложно и просто одновременно. Спасибо за контент.
Параллельно прохожу твой курс на Merion academy!
top!
спасибо❤
Лучшее объяснение по FastAPI!
Сурен, спасибо большое!
Будут ли видео про (docker + fastapi) ?
"…так, давайте в этот раз наберём СЕМЬДЕСЯТ лайков…" 😀
Реакция: положительная.
Рад, что порядок фидбека не оправдал ожидания, в лучшую сторону)
Приятно, когда хороший материал получает заслуженное внимание.
С другой стороны, немного страшно от количества интересующихся – успокаиваю себя тем, что большинство уже нашло работу и просто подтягивает те знания, которые уже и так должны были иметься (:
Да уж. Всегда встречался с проблемой при просмотре подобных видео, что информации полезной как таковой нет, наоборот – больше вопросов возникает. Тут совсем иначе: информации так много, что приходится делать перерывы на "переваривание" информации, ибо понимание дается очень трудно (хотя, чего я хотел, когда еще совсем недавно не знал, что за return у функций, лол).
Очень полезное видео, очень помогло. Жаль не рассмотрена работа с несколькими схемами, у меня обе ноги прострелены 😅
Спасибо Сурен!