Как стать автором
Обновить

Комментарии 24

Я указал этот момент в разделе «Сравнение с остальными ОРМ».
Сейчас в документации описано что это beta версия. Нужно какое то время подождать исправления всех проблем, на данный момент использовать эту версию с привязкой к asyncio рискованно
1.4 уже довольно давно зарелизилась, а я использовал -dev версию в проде ещё до её выхода.

У peewee асинхронная версия это отдельный проект, который отставал на несколько версий от синхронной версии(возможно, это уже не так).

В django есть костыли в виде sync_to_async/async_to_sync.

А вот tortoise мне понравился больше всего, сейчас для каких-то небольших проектов, типа ботов на aiogram, я беру именно её.
спасибо за подробный ответ!
В планах — попробовать асинхронную алхимию на одном из новых некритичных сервисов, и если она себя хорошо покажет — можно тиражировать этот опыт.
Но я думаю что ORM не подойдёт для сложных нагруженных сервисов, т к для разработчика не всегда понятна как она построит тот или иной запрос и не «положит ли бд» в каких то граничных случаях. Запросы без ORM гораздо проще прогнозировать и проверять через explain
Если знать как орм работает, то всё понятно. Кроме того, в django, например достаточно написать str(queryset) чтобы увидеть sql-запрос, есть ключил --print-sql в shell_plus который будет сразу печатать все sql запросы, которые выполняются. Есть debug_toolbar и silk которые покажут все sql запросы на странице и время их выполнение. Есть метод queryset.explain() docs.djangoproject.com/en/3.2/topics/db/optimization

В алхимии есть аналогичные средства, их даже больше т.к. она более навороченная и с её помощью можно выразить вообще любые запросы.

Но главное — это то, что запросы можно конструировать динамически, из кусочков. Например, добавлять условия в зависимости от параметров запроса. На «голом» sql это будет кошмар. Есть конструкторы запросов, но почему бы не использовать сразу orm. Потому что помимо этого орм обеспечивает средства для автоматических миграций и т.п. При наличие декларативных моделей можно автоматически создавать сериализаторы github.com/pawnhearts/aiorf/blob/master/aiorf/saschema.py и т.п.

А свою объектку менее рискованно?

Данная обёртка и полноценная ORM — разные вещи
В данном случае используется SQLAlchemy Core, он хорошо оттестирован, и обёртка нужна для уменьшения кол-ва кода и большей читаемости запросов

Я не имею ничего против статьи. Как образовательный материал — это очень хорошо. Но тянуть такое в прод я бы не стал. Возможно дело в моём травматическом опыте выпиливания "обертки" на алхимией.


В данном случае совершенно непонятно чем User.select() лучше чем select(User). Первое — ваше изобретение, второе — стандартный синтаксис. Очевидно, что новые члены команды будут порываться использовать второе. Я понимаю, что многие вещи вы реализовали, но в алхимии очень много полезных возможностей и в конце концов вам придется реализовать их все. Например, я не вижу having, не уверен насколько оно корректно работает с hybrid_property, alias или внешними ключами, ссылающимися на ту же таблицу (возможно проблемы нету, я не проводил эксперименты).


Так же не понятно, зачем ограничиваться core, когда вы и так используете declarative_base. Если речь идет о сокращении кода — как вы будете решать проблему N+1? Алхимия представляет механизм опций для загрузки relstionship. Это намного удобнее, чем руками писать джойны и подзапросы.


Есть подозрение, что материал немного устарел, сейчас в sqlalchemy идет работа по снижению отличий crore и orm. В частности рекомендую к ознакомлению Migrating to SQLAlchemy 2.0. В новом синтаксисе вы сначала подготавливаете запросы а потом выполняете их в сессии. При чем async и sync версия отличается только этапом выполнения запроса (фактически await словом в одном вызове). В связи с этим мне кажется, изобретение своего конструктора запросов поверх стандартного не актуальным.


Собственно что в бете? Работа самого async session. Конструкторы запросов и прочие механики работают в синхронной версии точно так же.

Неоднократно вижу, что люди пытаюсь в алхимии в модели запихнуть логику работы с соединением. Это нет очень хорошая идея. Все таки у нас не active record.

С точки зрения разделения зон ответственности, модель должна отвечать только за свои данные: данные экземпляра и как эти данные хранятся в бд. Например, сюда хорошо ложатся гибридные свойства и relationship. Если у вас регулярно фигурируют сложные выборки или агрегации, их можно оформить как отдельные модели (алхимия позволяет указать не имя таблицы, а запрос). За счёт этого мы в дальнейшем можем переиспользовать логику моделей в совершенно разных выборках или даже без непосредственно запросов БД.

Сама же отправка запросов в алхимии реализуется в session. Фактически этот объект представляет собой универсальный репозиторий доступа к хранилищу, который работает с моделями и построенными на основе них запросами.

Как я понимаю, для вас кажется муторным конструировать по месту запросы в том виде как это предлагает алихмия. В этом случае имеет смысл выделить их в отдельные функции или даже классы, но запихивать их в виде статикметодов достаточно странно, так как потом эти статики становятся доступны всем слоям приложения которые получают экземпляр модели, а это выглядит как протекание абстракций. В идеале конечно можно было бы воспользоваться "классическими мапперами", когда в качестве моделей выступают обычные датаклассы, но и грамотное использование моделей может быть быть неотличимо от них

Спасибо за подробное разъяснение.
Были идеи по удалению коннекта из функций модели. Но на aiopg это не очень удобно реализовывать. В новых проектах попробую реализовать эту логику через библиотеку databases.

Возможно у Вас есть примеры кода, в котором описанная выше логика реализована?

Удаление коннекта из модели — не более чем стиль, это не влияет на логику. Вам нужна механика превращения запроса в понятный коннектору — он у вас есть. И, вам нужен движок, который это умеет вызывать. Если подумать, получается, что я описываю async session алхимии: await session.execute(query). В этом случае вы можете разделить логику подготовки запросов и их выполнения. Или подготовить запрос один раз и переиспользовлать в разных местах.


Что касается databases — я не очень тесно с ним работал. Кажется, там были непонятки с жизненным циклом соединений. Плюс я категорически против подхода "автокоммит": найти потерянный коммит намного проще чем потерянную транзакцию. В этом плане мне нравится подход алхимии. Плюс databases раньше не умели relationship (не знаю, как сейчас).


В целом я бы посоветовал не пытаться сократить простые и очевидные места, которые при этом и так не слишком длинные.

спасибо

Гляньте ormar, молодая и амбициозная асинхронная django-like орм. Как то случайно наткнулся на неё.

спасибо, происследую проект

Есть асинхронная ормка ORMAR, тоже написанная на core alchemy

Спасибо! происследую реализацию
Мы во многих проектах используем Gino, вполне себе удобная и адекватная библиотека, не вижу смысла придумывать свои велосипеды, только вот:
Работать с этой библиотекой можно без знаний об SQLAlchemy.

это не совсем так — gino это по сути надстройка над SQLAlchemy Сore, поэтому если умеешь писать запросы на алхимии, то в gino по сути все тоже самое, особых проблем с переходом не будет.
Идея была такая — можно не учить SQLAlchemy Сore, достаточно документации самой Gino
Добрый день!
Когда добавите producer на статью «11 друзей Sanic’а – собираем асинхронное веб-приложение на Python»
Добрый день!
А что подразумевается под producer? Отправка сообщений в очередь(consumer/producer)? Или вопрос про продолжение?
да в проекте написали consumer, теперь как отправить сообщений в очередь(producer)?

с помощью библиотеки aioamqp: https://aioamqp.readthedocs.io/en/latest/api.html?highlight=publish#publishing-messages
в рамках проекта с boilerplate используется в функции consume_handler, когда нужно перекинуть сообщение с ошибкой в очередь с авторазбором
пример кода(канал уже поднят):
await channel.publish(payload=body, exchange_name='exchange', routing_key='routing_key')

данный кусочек на отдельную статью не тянет, может мимоходом упомяну в какой нибудь будущей публикации

Зарегистрируйтесь на Хабре , чтобы оставить комментарий