SQLAlchemy: How to use Session and ORM

  Рет қаралды 16,519

Артём Шумейко

Артём Шумейко

Күн бұрын

💡 Попробуй онлайн-тренажёр для подготовки к техническому собеседованию: 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 - Тот же запрос, но асинхронно

Пікірлер: 38
@artemshumeiko
@artemshumeiko 9 ай бұрын
💡 Попробуй онлайн-тренажёр для подготовки к техническому собеседованию: 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), то чтобы дойти до правильной реализации всех этих базовых механик (к примеру правильно создать асинхронную сессию с пулом соединений) я потратил прям значительное время))) с учетом того что у алхимии документация такая себе... Так что видео очень полезное, для кого-то может сэкономить кучу времени))))
@supreltd
@supreltd 2 ай бұрын
Пушка! При объяснении асинхрона, чтоб понимать где await нужен - нужно просто провалиться в сущность. Если это простая функция, типо add_all (def add_all(self, instances: Iterable[object]) -> None) или это поле - await не нужен. Если функция асинхронная (async def commit(self) -> Coroutine[Any, Any, None]) - await необходим :))
@szwajcendany5368
@szwajcendany5368 7 ай бұрын
Если не ошибаюсь, при создании модели с использованием mapped_column, указывать String из SQLAlchemy необходимо для указания длины слова
@georgiyveter6391
@georgiyveter6391 8 ай бұрын
Хорошо бы сделать обзор по сравнению скоростей core и orm на большом количестве данных.
@antonsachuk615
@antonsachuk615 4 ай бұрын
вопрос: я так понимаю, из-за того, что мы не удалили metadata_obj = MetaData() и описывали таблицы -> то у нас в методе create_tables создавались таблицы. И если убрать код с metadata_obj и workers_table - то будет ошибка, так как при вставке через orm -> будет исключение об отсутствии таблицы workers? или base работает так же, как и metadata obj?
@user-gd4en4ot3u
@user-gd4en4ot3u 5 ай бұрын
такой вопрос возник: можно ли забыть предыдущее видео как страшный сон?)) Я это к тому, что в этом видео описан декларативный метод, который в 100 раз лучше императивного
@kreynie
@kreynie 8 ай бұрын
Было бы классно увидеть абстрактные классы для таблиц, их связи с помощью relationship между собой и другими таблицами
@artemshumeiko
@artemshumeiko 8 ай бұрын
Классы будут в следующем видео. А relationships через 4-5 видео
@user-ql6lk9uq4x
@user-ql6lk9uq4x 2 ай бұрын
в чем логика? Артём перешёл от одного способа представления к другому свалив всё в одну кучу (при этом методы core и orm разделены), при этом проигнорировав метод создания таблицы или как-то это пояснив. Урок после которого ещё нужно гуглить и разбирать котлеты от мух. Круто!
@alexz7537
@alexz7537 Ай бұрын
Подскажите, а мы после синхронной сессии в базе данных затирали данные? Упустил это момент. Или почему у нас в БД нет дубликатов бобра и волка после повторного внесения с асинхронной сессией?
@hovharoyan3262
@hovharoyan3262 3 ай бұрын
Спасибо за урок!Подскажите, пожалуйста, когда мы используем imperative стиль, то нам следует использовать from sqlalchemy import insert,update и тд.?
@artemshumeiko
@artemshumeiko 3 ай бұрын
from sqlalchemy import insert,update используется во всех стилях
@user-gd4en4ot3u
@user-gd4en4ot3u 5 ай бұрын
А вы не знаете какой есть асинхронный драйвер для MySQL?
@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() для создания таблиц. В конце курса мы посмотрим на механизм миграций, который позволяет переносить модели в базу данных более элегантно
@evgeniykanovalov3372
@evgeniykanovalov3372 7 ай бұрын
Артём, здравствуйте, подскажите, в чем разница между declarative_base и DeclarativeBase. Как я понял declarative_base это какая-то фабрика (Base = declarative_base() и потом модели так же наследуются от Base)
@artemshumeiko
@artemshumeiko 7 ай бұрын
Объявление через наследование класса - более современный подход, чтобы можно было в этом же классе переопределять какието атрибуты и методы. В старом подходе для этого нужно заводить новый класс, наследуясь от Base
@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)
@Qustoos
@Qustoos 6 ай бұрын
В чем отличия Column от Mapped? Если я правильно понял то они оба выполняет похожие действия: добавляют некоторые метаданные для поля, например макс длина строки, nullable и т.д. Но Column старый формат а Mapped современный?
@artemshumeiko
@artemshumeiko 6 ай бұрын
Да, column - старый, mapped - новый. Все отличие в типизации. Других изменений нет
@xesax
@xesax 3 ай бұрын
почему здесь используется add вместо insert? в платном курсе везде insert
@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 3 ай бұрын
внутри fastapi нельзя испоьзовать asyncio.run(), так как уже используется внутренний событийный цикл фреймворка. Достаточно просто делать await insert_data() в нужных местах кода. Например, в lifespan (см доку) при запуске fastapi
@taniilves
@taniilves 3 ай бұрын
@@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, который позволяет работать со строками базы как с объектами питона, а так же запоминает все-все добавленные в сессию объекты, чтобы потом по красоте в нужном порядке отправить запросы в базу данных. Используйте тот подход, который вам больше нравится. Если говорить про скорость работы программы в каждом подходе, то первый будет быстрее, хоть и не сильно. Чуть дальше по курсу я еще раз проясню разницу в использовании этих подходов.
SQLAlchemy: How to create tables with classes - Mapped + mapped_column #5
18:13
Артём Шумейко
Рет қаралды 16 М.
SQLAlchemy: SELECT and UPDATE queries with ORM vs CORE #6
28:11
Артём Шумейко
Рет қаралды 14 М.
WHY IS A CAR MORE EXPENSIVE THAN A GIRL?
00:37
Levsob
Рет қаралды 21 МЛН
New Gadgets! Bycycle 4.0 🚲 #shorts
00:14
BongBee Family
Рет қаралды 17 МЛН
Универ. 13 лет спустя - ВСЕ СЕРИИ ПОДРЯД
9:07:11
Комедии 2023
Рет қаралды 4,2 МЛН
Unit 29 | Lesson 08 | Abstraction | C#
29:20
DP Education IT Campus
Рет қаралды 1
Raw SQL, SQL Query Builder, or ORM?
16:19
ArjanCodes
Рет қаралды 94 М.
Стоит ли идти в IT в 2024 году?
7:02
Таня Овчинникова
Рет қаралды 9 М.
ИНДЕКСЫ В БАЗАХ ДАННЫХ. СОБЕС В OZON.
33:59
Ваня Ио про разработку
Рет қаралды 41 М.
WHY IS A CAR MORE EXPENSIVE THAN A GIRL?
00:37
Levsob
Рет қаралды 21 МЛН