Согласен, что сессия реализует UoW и Identity Map, и это хорошие паттерны. Но в SQLAlchemy сессия — это не только они. Это ещё и точка входа ко всем операциям с БД (query, execute, bind), управление транзакциями и жизненный цикл объектов. Когда сервис делает session.get() или session.add(), он работает не с абстрактным хранилищем, а с конкретным механизмом SQLAlchemy, который требует понимания, когда происходит flush, когда объект становится detached и т.д. В этом смысле детали БД (точнее, детали ORM-провайдера) реально просачиваются в код сервиса
Вы правы, что в каноне DDD репозиторий возвращает бизнес-сущности. Но в стандартном использовании SQLAlchemy (declarative mapping) класс модели чаще описывает столбцы таблицы и relationships, а не богатое доменное поведение. Да, SQLAlchemy позволяет императивный маппинг и Data Mapper, и это отлично, когда нужно разделить домен и БД. Но «из коробки» и в большинстве проектов модель — это по сути отражение таблицы с метаданными ORM. Именно поэтому я выделяю DTO/отдельный слой: чтобы сервис получал чистый объект без SQLAlchemy-специфичных атрибутов (instrumented attributes, state), которые не имеют отношения к бизнес-логике
Здесь полностью согласен — это проблема. И да, её можно контролировать (отключать lazy, использовать raise on SQL, eager loading). Но факт в том, что по умолчанию SQLAlchemy настроен так, что объект может незаметно порождать запросы или падать при обращении к атрибуту вне сессии. Это требует дисциплины и знания внутренностей ORM, и именно этого я пытаюсь избежать
Про container.transaction() - это не про глобальные переменные, а про несколько репозиториев, объединённых одной сессией. container в данном случае точно также может динамически создаваться, как и любая другая переменная. Делать его глобальным или нет - это уже от пользователя зависит
ИМХО, слишком много способов сделать одно и то же. Это опять же не столько проблема, сколько как будто просто не всегда подходящий инструмент. Если человек отлично разбирается в SQLAlchemy и у него уже есть готовый паттерн работы с ней - почему нет? У меня за время работы тоже сформировался паттерн - именно его я и оформил в отдельную библиотеку
Ну и впринципе, вы рассматриваете инструмент со стороны прожённого разработчика и видите как плохо он подходит для продакшен big tech продукта. Как я и писал, если бы я делал большой продукт с целой командой разработки - я бы выбрал SQLAlchemy. Но для пет-проектов мне кажется это лишнее. CRUD, транзакции, join-ы - что ещё нужно?
К сожалению, аналогично далёк от PHP разработки, но постараюсь ответить
1. Как писал в статье - есть зависимость от pydantic-filters, пофикшенная версия которой есть только на GitHub. Но недавно разработчик библотеки выложил версию 4.0.0 на PyPI, так что я теперь тоже могу выложить MetaORM на PyPI
2. К сожалению, не знаком со скоупами. Было бы здорово, если бы вы рассказали, какие дополнительные возможности имеют скоупы и чего не хватает?
3. Тоже не очень понял, что имеется ввиду под Fluent Interface для фильтров. Если это то, что я думаю, то я видел таких самописные реализации в каждом проекте, они все имеют одинаковую логику, но разную реализацию. Своим решением хотел это унифицировать сделать более Pythonic-way, что ли
Спасибо, действительно ошибка. Дело не в микросервисах и не в том, что это "проблема". Скорее базовая задача, которая должна решаться проще и более нативно, чем session.begin/session.end, ИМХО
Видимо, не так выразился. Как вы и сказали - 90% CRUD - это уже место, где кажется можно использовать более высокоуровневые абстракции и не лезть в особенности работы с БД, но даже sessions.get/sessions.add ими сквозят во всю
Как минимум не получится делать динамическое добавление тулзов в рантайме (вариант динамической пересборки бинарника я бы не хотел рассматривать). Как максимум - это непросто для конечного пользователя. Мне кажется, что популярность системе придаёт ещё лёгкость деплоя и конфигурации, как в том же OpenClaw, например
Вы смешали понятия MCP сервера и LangChain тулзы, а я, возможно, не очень хорошо разграничил эти понятия. Для MCP сервера не надо пересобирать образ, но я отдаю предпочтение работы именно через тулзы, потому что если хочется начинить своего агента кучей возможностей, то, ИМХО, поднимать под каждую функцию отдельный процесс - именно это на самом деле вызовет избыток потребления CPU и RAM, который уже даже агент на Rust не перекроет
Видимо в облачном провайдере заранее изучили и настроили OpenClaw. Но, как вы правильно заметили, если не забрать доступ к файловой системе и запуску чего-то в терминале - возможно всё. Только перед этим агент ещё и сожрёт миллионы токенов
Рассуждал, но не исследовал. Единственная моя теория - что это первый агент, который действительно может сделать практически всё благодаря тулзам, которые открывают доступ к файловой системе и терминалу. Все остальные - это уже последователи со своими фишками
Извините, не собираюсь делать вид, почему "суверенный" должен сразу означать, что мы должны с нуля пересоздавать протоколы и делать свою маршрутизацию, плюс мне казалось, что в заголовке очень явно написал, что в статье будет разобрано - о маршрутизации ни слово.
По поводу Reticulum - это очень интересно, но непонятно, как это будет работать в рамках закона КоАП РФ 13.4.
Читал, и, если честно, не ожидал, что кто-то всерьёз будет воспринимать это как гайд, даже в статье в кавычки поместил. Ну если действительно интересно, то это уже вопрос отдельной статьи, я этим не занимался и просто хотел показать, что это далеко не просто (даже в далёком 2011 году и зарубежом)
Согласен, что сессия реализует UoW и Identity Map, и это хорошие паттерны. Но в SQLAlchemy сессия — это не только они. Это ещё и точка входа ко всем операциям с БД (query, execute, bind), управление транзакциями и жизненный цикл объектов. Когда сервис делает
session.get()илиsession.add(), он работает не с абстрактным хранилищем, а с конкретным механизмом SQLAlchemy, который требует понимания, когда происходит flush, когда объект становится detached и т.д. В этом смысле детали БД (точнее, детали ORM-провайдера) реально просачиваются в код сервисаВы правы, что в каноне DDD репозиторий возвращает бизнес-сущности. Но в стандартном использовании SQLAlchemy (declarative mapping) класс модели чаще описывает столбцы таблицы и relationships, а не богатое доменное поведение. Да, SQLAlchemy позволяет императивный маппинг и Data Mapper, и это отлично, когда нужно разделить домен и БД. Но «из коробки» и в большинстве проектов модель — это по сути отражение таблицы с метаданными ORM. Именно поэтому я выделяю DTO/отдельный слой: чтобы сервис получал чистый объект без SQLAlchemy-специфичных атрибутов (instrumented attributes, state), которые не имеют отношения к бизнес-логике
Здесь полностью согласен — это проблема. И да, её можно контролировать (отключать lazy, использовать raise on SQL, eager loading). Но факт в том, что по умолчанию SQLAlchemy настроен так, что объект может незаметно порождать запросы или падать при обращении к атрибуту вне сессии. Это требует дисциплины и знания внутренностей ORM, и именно этого я пытаюсь избежать
Про container.transaction() - это не про глобальные переменные, а про несколько репозиториев, объединённых одной сессией. container в данном случае точно также может динамически создаваться, как и любая другая переменная. Делать его глобальным или нет - это уже от пользователя зависит
ИМХО, слишком много способов сделать одно и то же. Это опять же не столько проблема, сколько как будто просто не всегда подходящий инструмент. Если человек отлично разбирается в SQLAlchemy и у него уже есть готовый паттерн работы с ней - почему нет? У меня за время работы тоже сформировался паттерн - именно его я и оформил в отдельную библиотеку
Само понятие сессии
Напрямую использование модели таблицы вместо DTO слоя
Настроенный по умолчанию lazy loading выстрелит в ногу при использовании объекта записи вне сессии
У меня вообще не открывается, даже по VPN(
Ну и впринципе, вы рассматриваете инструмент со стороны прожённого разработчика и видите как плохо он подходит для продакшен big tech продукта. Как я и писал, если бы я делал большой продукт с целой командой разработки - я бы выбрал SQLAlchemy. Но для пет-проектов мне кажется это лишнее. CRUD, транзакции, join-ы - что ещё нужно?
К сожалению, аналогично далёк от PHP разработки, но постараюсь ответить
1. Как писал в статье - есть зависимость от pydantic-filters, пофикшенная версия которой есть только на GitHub. Но недавно разработчик библотеки выложил версию 4.0.0 на PyPI, так что я теперь тоже могу выложить MetaORM на PyPI
2. К сожалению, не знаком со скоупами. Было бы здорово, если бы вы рассказали, какие дополнительные возможности имеют скоупы и чего не хватает?
3. Тоже не очень понял, что имеется ввиду под Fluent Interface для фильтров. Если это то, что я думаю, то я видел таких самописные реализации в каждом проекте, они все имеют одинаковую логику, но разную реализацию. Своим решением хотел это унифицировать сделать более Pythonic-way, что ли
В этом и суть! Она крошечная
И меня зовут Олег, вынужден поправить
Спасибо, действительно ошибка. Дело не в микросервисах и не в том, что это "проблема". Скорее базовая задача, которая должна решаться проще и более нативно, чем session.begin/session.end, ИМХО
Видимо, не так выразился. Как вы и сказали - 90% CRUD - это уже место, где кажется можно использовать более высокоуровневые абстракции и не лезть в особенности работы с БД, но даже sessions.get/sessions.add ими сквозят во всю
Как минимум не получится делать динамическое добавление тулзов в рантайме (вариант динамической пересборки бинарника я бы не хотел рассматривать). Как максимум - это непросто для конечного пользователя. Мне кажется, что популярность системе придаёт ещё лёгкость деплоя и конфигурации, как в том же OpenClaw, например
Вы смешали понятия MCP сервера и LangChain тулзы, а я, возможно, не очень хорошо разграничил эти понятия. Для MCP сервера не надо пересобирать образ, но я отдаю предпочтение работы именно через тулзы, потому что если хочется начинить своего агента кучей возможностей, то, ИМХО, поднимать под каждую функцию отдельный процесс - именно это на самом деле вызовет избыток потребления CPU и RAM, который уже даже агент на Rust не перекроет
Потому что система навыков съедает токены очень быстро, а добавление каждого нового тулза - это пересборка бинарника
Уже есть, кстати, по явным запросам "запомни" и "вспомни" работает
Тоже интересно) надеюсь, я не первый
Видимо в облачном провайдере заранее изучили и настроили OpenClaw. Но, как вы правильно заметили, если не забрать доступ к файловой системе и запуску чего-то в терминале - возможно всё. Только перед этим агент ещё и сожрёт миллионы токенов
Рассуждал, но не исследовал. Единственная моя теория - что это первый агент, который действительно может сделать практически всё благодаря тулзам, которые открывают доступ к файловой системе и терминалу. Все остальные - это уже последователи со своими фишками
Но не глубже
Не согласен, llm-ка справилась бы намного лучше с приведением аргументов, чем автор
У меня нет уверенности не в том, что он есть, а в том, что он будет и причём глобально по всей стране
Извините, не собираюсь делать вид, почему "суверенный" должен сразу означать, что мы должны с нуля пересоздавать протоколы и делать свою маршрутизацию, плюс мне казалось, что в заголовке очень явно написал, что в статье будет разобрано - о маршрутизации ни слово.
По поводу Reticulum - это очень интересно, но непонятно, как это будет работать в рамках закона КоАП РФ 13.4.
Читал, и, если честно, не ожидал, что кто-то всерьёз будет воспринимать это как гайд, даже в статье в кавычки поместил. Ну если действительно интересно, то это уже вопрос отдельной статьи, я этим не занимался и просто хотел показать, что это далеко не просто (даже в далёком 2011 году и зарубежом)