Тёмный

SQLAlchemy: How to use Session and ORM 

Артём Шумейко
Подписаться 28 тыс.
Просмотров 16 тыс.
50% 1

💡 Попробуй онлайн-тренажёр для подготовки к техническому собеседованию: clck.ru/3B5gxT 💡
Предзапись на курс по поиску работы разработчику и техническим навыкам для Middle: forms.gle/Zw7bPnQvTsfekVH47
Забирай роадмап изучения самого востребованного фреймворка на Python - FastAPI здесь: t.me/ArtemShumeikoBot
Все вопросы по SQLAlchemy обсуждаем в телеграм сообществе: t.me/python_community_rus
Мой телеграм канал о жизни разработчика: t.me/artemshumeiko
Полезные материалы для бэкендера в моем телеграм боте: t.me/ArtemShumeikoBot?start=eXQ
Репозиторий на Github с кодом из видео: t.me/artemshumeiko/28
Поддержать меня и получить ранний доступ к видео можно здесь: boosty.to/artemshumeiko
Сегодня прикоснемся к Session и ORM, научимся манипулировать Python объектами вместо сырых SQL запросов.
0:00 - Session и sessionmaker
2:38 - Объявление таблицы через класс (Mapped и mapped_column)
6:46 - Вставка данных через ORM - session.add(...)
11:26 - Тот же запрос, но асинхронно

Опубликовано:

 

15 июн 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 38   
@artemshumeiko
@artemshumeiko 8 месяцев назад
💡 Попробуй онлайн-тренажёр для подготовки к техническому собеседованию: clck.ru/3B5gwP 💡 Забирай роадмап изучения самого востребованного фреймворка на Python - FastAPI здесь: t.me/ArtemShumeikoBot
@user-oc5sd1jw4n
@user-oc5sd1jw4n 8 месяцев назад
Спасибо за урок! Для инфо, может кому-то будет полезно: если нужно табличку workers создать не в дефолт-схеме public, а в какой-то своей, то после __tablename__ можно использовать __table_args__ = {"schema": "myschemaname"}
@vasisafronov
@vasisafronov 8 месяцев назад
Казалось бы никакой магии не показал автор, но на самом деле когда мне понадобилось использовать алхимию (я мидл разраб с не самым большим опытом, до этого всегда юзал SQL через asyncpg), то чтобы дойти до правильной реализации всех этих базовых механик (к примеру правильно создать асинхронную сессию с пулом соединений) я потратил прям значительное время))) с учетом того что у алхимии документация такая себе... Так что видео очень полезное, для кого-то может сэкономить кучу времени))))
@szwajcendany5368
@szwajcendany5368 7 месяцев назад
Если не ошибаюсь, при создании модели с использованием mapped_column, указывать String из SQLAlchemy необходимо для указания длины слова
@supreltd
@supreltd 2 месяца назад
Пушка! При объяснении асинхрона, чтоб понимать где await нужен - нужно просто провалиться в сущность. Если это простая функция, типо add_all (def add_all(self, instances: Iterable[object]) -> None) или это поле - await не нужен. Если функция асинхронная (async def commit(self) -> Coroutine[Any, Any, None]) - await необходим :))
@georgiyveter6391
@georgiyveter6391 8 месяцев назад
Хорошо бы сделать обзор по сравнению скоростей core и orm на большом количестве данных.
@antonsachuk615
@antonsachuk615 4 месяца назад
вопрос: я так понимаю, из-за того, что мы не удалили metadata_obj = MetaData() и описывали таблицы -> то у нас в методе create_tables создавались таблицы. И если убрать код с metadata_obj и workers_table - то будет ошибка, так как при вставке через orm -> будет исключение об отсутствии таблицы workers? или base работает так же, как и metadata obj?
@alexz7537
@alexz7537 29 дней назад
Подскажите, а мы после синхронной сессии в базе данных затирали данные? Упустил это момент. Или почему у нас в БД нет дубликатов бобра и волка после повторного внесения с асинхронной сессией?
@WillieDvin
@WillieDvin 7 месяцев назад
Извините, разрешите уточнить, а то я что-то запутался. на 2:53 Вы сказали что metadata_obj и функция create_tables() больше не нужны. но все таки таблицы создались через них. получается и они нужны и Table и Column и прочее, и допом к ним идет класс WorkersOrm(Base), который сам не создает таблицы в postgresql? --- А вот в следующем видео нашел конструкцию Base.metadata.create_all(engine). Вот теперь и MetaData() и таблицы созданные с помощью Table() Column() и тд не нужны.
@artemshumeiko
@artemshumeiko 7 месяцев назад
> но все таки таблицы создались через них к сожалению, забыл поменять metadata_obj на Base.metadata. Действительно, metadata_obj больше не нужен > и допом к ним идет класс WorkersOrm(Base), который сам не создает таблицы в postgresql? верно, само наличие класса никак не отражается на базе данных, нам по прежнему нужно использовать Base.metadata.create_all() для создания таблиц. В конце курса мы посмотрим на механизм миграций, который позволяет переносить модели в базу данных более элегантно
@user-gd4en4ot3u
@user-gd4en4ot3u 5 месяцев назад
такой вопрос возник: можно ли забыть предыдущее видео как страшный сон?)) Я это к тому, что в этом видео описан декларативный метод, который в 100 раз лучше императивного
@hovharoyan3262
@hovharoyan3262 3 месяца назад
Спасибо за урок!Подскажите, пожалуйста, когда мы используем imperative стиль, то нам следует использовать from sqlalchemy import insert,update и тд.?
@artemshumeiko
@artemshumeiko 3 месяца назад
from sqlalchemy import insert,update используется во всех стилях
@user-gd4en4ot3u
@user-gd4en4ot3u 5 месяцев назад
А вы не знаете какой есть асинхронный драйвер для MySQL?
@evgeniykanovalov3372
@evgeniykanovalov3372 7 месяцев назад
Артём, здравствуйте, подскажите, в чем разница между declarative_base и DeclarativeBase. Как я понял declarative_base это какая-то фабрика (Base = declarative_base() и потом модели так же наследуются от Base)
@artemshumeiko
@artemshumeiko 7 месяцев назад
Объявление через наследование класса - более современный подход, чтобы можно было в этом же классе переопределять какието атрибуты и методы. В старом подходе для этого нужно заводить новый класс, наследуясь от Base
@kreynie
@kreynie 8 месяцев назад
Было бы классно увидеть абстрактные классы для таблиц, их связи с помощью relationship между собой и другими таблицами
@artemshumeiko
@artemshumeiko 8 месяцев назад
Классы будут в следующем видео. А relationships через 4-5 видео
@user-ql6lk9uq4x
@user-ql6lk9uq4x 2 месяца назад
в чем логика? Артём перешёл от одного способа представления к другому свалив всё в одну кучу (при этом методы core и orm разделены), при этом проигнорировав метод создания таблицы или как-то это пояснив. Урок после которого ещё нужно гуглить и разбирать котлеты от мух. Круто!
@user-eo4kd9dt1e
@user-eo4kd9dt1e 8 месяцев назад
Курс бомба) Но появился вопрос, в чем отличие session.add() от session.execute()?
@saitaro
@saitaro 8 месяцев назад
.add() добавляет задачи, которые будут реализованы с помощью .execute() в рамках транзакции
@B0JIKA
@B0JIKA 4 месяца назад
13:04 Если использовать sqlite, по получаю ошибку, когда таблицы создаются синхронно, а данные добавляются асинхронно. Если переделать, чтоб таблицы и данные создавались асинхронно, то проходит без ошибок.
@B0JIKA
@B0JIKA 4 месяца назад
разобрался, я базы создавал в памяти ```python from sqlalchemy import create_engine, Engine from sqlalchemy.ext.asyncio import create_async_engine, AsyncEngine, AsyncSession, async_sessionmaker from sqlalchemy.orm import Session, sessionmaker, DeclarativeBase sync_engine: Engine = create_engine( url="sqlite+pysqlite:///:memory:", echo=True, # pool_size=5, # max_overflow=10, ) async_engine: AsyncEngine = create_async_engine( url="sqlite+aiosqlite:///:memory:", echo=True, # pool_size=5, # max_overflow=10, ) async_session_factory = async_sessionmaker(async_engine) sync_session_factory = sessionmaker(sync_engine) ``` получалось, что синхронный и асинхронный код ссылались на разные объекты в памяти. и выглядело это так, что таблица не создана... sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: workers [SQL: INSERT INTO workers (username) VALUES (?) RETURNING id] [parameters: ('Bobr',)] (Background on this error at: sqlalche.me/e/20/e3q8)
@xesax
@xesax 3 месяца назад
почему здесь используется add вместо insert? в платном курсе везде insert
@Qustoos
@Qustoos 6 месяцев назад
В чем отличия Column от Mapped? Если я правильно понял то они оба выполняет похожие действия: добавляют некоторые метаданные для поля, например макс длина строки, nullable и т.д. Но Column старый формат а Mapped современный?
@artemshumeiko
@artemshumeiko 6 месяцев назад
Да, column - старый, mapped - новый. Все отличие в типизации. Других изменений нет
@taniilves
@taniilves 3 месяца назад
Уже не первый раз при попытке использования асинхронщины в FastAPI получаю ошибку: RuntimeError: asyncio.run() cannot be called from a running event loop sys:1: RuntimeWarning: coroutine 'insert_data' was never awaited RuntimeWarning: Enable tracemalloc to get the object allocation traceback Даже если полностью скопировать код из документации, все равно такая ошибка. Нигде не могу найти четкого и простого объяснения что с этим делать.
@artemshumeiko
@artemshumeiko 2 месяца назад
внутри fastapi нельзя испоьзовать asyncio.run(), так как уже используется внутренний событийный цикл фреймворка. Достаточно просто делать await insert_data() в нужных местах кода. Например, в lifespan (см доку) при запуске fastapi
@taniilves
@taniilves 2 месяца назад
@@artemshumeiko Спасибо. Мне, похоже, предстоит ещё долго во всем этом разбираться, так как опыта маловато...
@memeger89
@memeger89 7 месяцев назад
Зачем вам два типа сессий?
@artemshumeiko
@artemshumeiko 7 месяцев назад
engine - легковесная, если не нужен функционал ORM sessionmaker - тяжеловесная, если нужен ORM
@memeger89
@memeger89 7 месяцев назад
​@@artemshumeiko я имел ввиду sync и async
@artemshumeiko
@artemshumeiko 7 месяцев назад
чтобы показать оба варианта использования сессии. Курс для всех -- и тех, кто вынужден сидеть на легаси проектах или проектах с синхронной сессией, и для тех, кто работает с асинхронной Алхимией
@nonstop249
@nonstop249 8 месяцев назад
Сам по новой начал постигать алхимию (последний раз юзал v1.4). Возник вопрос, как лучше делать запрос на создание записи/записей в v2.0. Как я понял по новому стилю принять писать statement, и для создания будет что-то вроде этого: stmt = insert(WorkersOrm).values([{"username": "Bobr"}, {"username": "Volk"}]).returninig("*") res = await session.execute(stmt) workers_db = res.fetchall() # тут кстати сразу будут доступны id новых воркеров, которые можно юзать до коммита await session.commit() А в старом варианте: worker_1 = WorkersOrm(username="Bobr") worker_2 = WorkersOrm(username="Volk") session.add_all([worker_1, worker_2]) await session.commit() Какой из этих вариантов более предпочтителен, на твой взгляд, или все равно?)
@artemshumeiko
@artemshumeiko 8 месяцев назад
Вы описали не старый и новый подходы, а два разных современных подхода. В настоящее время они оба используются. Первый использует знакомый SQL язык в питонячьей обертке. Второй использует паттерн Unit Of Work, который позволяет работать со строками базы как с объектами питона, а так же запоминает все-все добавленные в сессию объекты, чтобы потом по красоте в нужном порядке отправить запросы в базу данных. Используйте тот подход, который вам больше нравится. Если говорить про скорость работы программы в каждом подходе, то первый будет быстрее, хоть и не сильно. Чуть дальше по курсу я еще раз проясню разницу в использовании этих подходов.
Далее
ДЖОНИ КИНУЛ ОСКАРА НА БАБКИ 🤑
01:00
Raw SQL, SQL Query Builder, or ORM?
16:19
Просмотров 94 тыс.
Основы и секреты Rest API
5:13
Просмотров 2 тыс.
Оператор SELECT | Основы SQL
7:01
Просмотров 122 тыс.
Git MERGE vs REBASE
16:12
Просмотров 1 млн
SQLAlchemy Turns Python Objects Into Database Entries
22:23