А скобки вокруг усолвия в if можно? а для моего товарища не надо. И синтаксис объявления словаря адаптировать. А, если мы пишем со скобками, то наверно язык не умеет в распаковку слева от =, можно тоже убрать?
Моя позиция простая: лучше освоить один какой-то способ использования алхимии, чем изучать какую-то левую библиотеку, которая точно не позволит многое сделать и придется потом с неё слезать
Сессия не имеет отношения к БД, это UoW + IdentityMap. Благодаря её наличию вы можете быть уверены что два последнующих вызова session.get(Model, id) вернут один и тот же инстанс модели. Плюс понятно к чему привязана транзакция. В вашей реализации container.transaction() вообще хз на что влияет, использование глобальных переменных - очень привлекательная для новичков идея (хз почему), которая потом стреляет при усложнении кода
Не путайте модель и таблицу. Модель - это бквально ваша бизнес сущность. Если почитать того же Фаулера/Эванса - репозиторий возвращает именно сущности. DTO используется когда мы реализуем не репозиотрии, а просто скрываем операции с БД (читай DAO/TableGateway), то есть когда бизнес логика построена не вокруг понятных объектов со своим стейтом, а более фрагментарно. Этот подход имеет место, но надо понимать ограничения. В случае ORM же модель - это именно бизнес сущность, которая каким-то способом маппится на хранилище (у вас DataMapper на схеме был). В случае алхимии есть несколько способов маппинга, в том числе императивный, если вам не нравится самый простой где модель равна таблице.
lazy load действительно проблема. К счастью, не использовать релейшены по принципу "щас гружу, потом не гружу", то всё становится проще.
Обычно для сервиса требуется CRUD для данных и взаимосвязи между таблицами, и больше ничего.
Неправда. Если даже в сервисе 90% кода это crud, набирается регулярно несколько интересных мест с динамическими запросами, хитрыми джойнами и прочими пирогами. В этом плане алхимия оказывается самым простыми и гибким решением: где надо делаешь session.get/add, а где надо - полноценный query builder. Главное понимать, что с ней конструирование хитрых update запросов - это уже не ORM, к select это не относится
Hot-reload. Наверное, самый важный DX функционал в любом фреймворке. До текущего дня, уверен, вы перезапускали аж всего бота, чтобы увидеть минорные изменения кода.
Я настолько привык что оно во многих случаях глючит или не работает, что просто не юзаю нигде.
RBAC (Role Based Access Control) это классика.
классика, которой почти всегда не хватает. Что насчет ReBAC? В целом я не очень люблю, когда логику проверки прав переносят из БЛ в фреймворк.
Диалоги использовать в высоконагруженных ботах не рекомендуется, в связи с тем, что они используют asyncio.Future и удерживают пул сессий.
Проблема не только в нагрузке (полагаю речь про горизонтальное масштабирование), но и в том что при рестарте бота эта информация будет потеряна.
Интерфейс абстрактной фабрики в вашем случае - требование наличие метода create. Он имеет смысл, потому что мы можем сказать "вот сюда передайте любой объект с методом create". А как вы собираетесь описывать интерфейс для фабричного метода у меня вызывает вопрос, ведь в основном фабричный метод используется внутри того же класса (см. паттерн шаблонный метод)
Sorry, перечитал внимательно, фабричные методы на месте, но как-то впепремешку с фабриками. Вы там ещё и интерфейс для фабричных методов предлагаете и промпт у вас по запросу фабричного метода абстрактную фабрику выдал.
По моему личному опыту ИИ-тексты отличаются поразительно низким количеством полезной информации на единицу контента. Бывает читаешь, читаешь, вроде интересно, а что прочитал - непонятно. Три раза одну мысль перевернули по разному, досыпали несвязанных фактов, пропустили логические цепочки, никаких выводов или деталей, позволяющих эти выводы сделать самим. Конечно, так же пишут и некоторые копирайтеры, но это не в плюс к ним.
exec-кодогенерация не меняет подход к созданию объектов, она позволяет делать инайлнинг, вырезание веток и разворачивание циклов.
Условно, до кодгена был такой код
res = cls(*(container.get(d) for d in deps))
if cached:
cache[cls] = res
то, имея cached=False, а deps=[int, str, A], мы можем вырезать иф, убрать распаковку и сгенерировать
res = cls(container.get(int), container.get(str), container.get(A))
Резвол асинк зависимостей в dishka есть, то я бы рекомендовал с этим быть осторожнее. С большой вероятностью (вероятно не всегда), если вы делает async-вызов при создании ресурса, вы смешиваете бизнес логику и просто получение зависимости. При этом я понимаю, что избежать async вызова при финализации ресурса будет сложнее
Канонические формы привязаны к языку программирования. Переводить надо между ними
А скобки вокруг усолвия в if можно? а для моего товарища не надо. И синтаксис объявления словаря адаптировать. А, если мы пишем со скобками, то наверно язык не умеет в распаковку слева от =, можно тоже убрать?
Моя позиция простая: лучше освоить один какой-то способ использования алхимии, чем изучать какую-то левую библиотеку, которая точно не позволит многое сделать и придется потом с неё слезать
Сессия не имеет отношения к БД, это UoW + IdentityMap. Благодаря её наличию вы можете быть уверены что два последнующих вызова session.get(Model, id) вернут один и тот же инстанс модели. Плюс понятно к чему привязана транзакция. В вашей реализации
container.transaction()вообще хз на что влияет, использование глобальных переменных - очень привлекательная для новичков идея (хз почему), которая потом стреляет при усложнении кодаНе путайте модель и таблицу. Модель - это бквально ваша бизнес сущность. Если почитать того же Фаулера/Эванса - репозиторий возвращает именно сущности. DTO используется когда мы реализуем не репозиотрии, а просто скрываем операции с БД (читай DAO/TableGateway), то есть когда бизнес логика построена не вокруг понятных объектов со своим стейтом, а более фрагментарно. Этот подход имеет место, но надо понимать ограничения. В случае ORM же модель - это именно бизнес сущность, которая каким-то способом маппится на хранилище (у вас DataMapper на схеме был). В случае алхимии есть несколько способов маппинга, в том числе императивный, если вам не нравится самый простой где модель равна таблице.
lazy load действительно проблема. К счастью, не использовать релейшены по принципу "щас гружу, потом не гружу", то всё становится проще.
Какие особенности работы с бд сквозят из session.get(Model, id) и session.add(model)?
Мне в целом нравится вариант когда транзакция начинается сама с первым запросом, а заканчивается когда сделаешь commit. Просто и надежно, не забудешь
А в чем проблема с алхимией в пет проектах?
Простите, что? Транзакции - базовая вещь, откуда это вообще проблема. И при чем тут микросервсы? У каждого сервиса свои таблицы и свои транзакции
Неправда. Если даже в сервисе 90% кода это crud, набирается регулярно несколько интересных мест с динамическими запросами, хитрыми джойнами и прочими пирогами. В этом плане алхимия оказывается самым простыми и гибким решением: где надо делаешь session.get/add, а где надо - полноценный query builder. Главное понимать, что с ней конструирование хитрых update запросов - это уже не ORM, к select это не относится
Я настолько привык что оно во многих случаях глючит или не работает, что просто не юзаю нигде.
классика, которой почти всегда не хватает. Что насчет ReBAC? В целом я не очень люблю, когда логику проверки прав переносят из БЛ в фреймворк.
Проблема не только в нагрузке (полагаю речь про горизонтальное масштабирование), но и в том что при рестарте бота эта информация будет потеряна.
Рассматривали ли вы
aiogram_dialogв этом месте?Да, я не понимаю как вы собираетесь использовать интерфейс при реализации паттерна фабричный метод
Интерфейс абстрактной фабрики в вашем случае - требование наличие метода
create. Он имеет смысл, потому что мы можем сказать "вот сюда передайте любой объект с методом create". А как вы собираетесь описывать интерфейс для фабричного метода у меня вызывает вопрос, ведь в основном фабричный метод используется внутри того же класса (см. паттерн шаблонный метод)Sorry, перечитал внимательно, фабричные методы на месте, но как-то впепремешку с фабриками. Вы там ещё и интерфейс для фабричных методов предлагаете и промпт у вас по запросу фабричного метода абстрактную фабрику выдал.
Я может невнимательно читал, но не вижу в статье фабричных методов. Везде отдельный класс-фабрика
Но ведь Factory и Factory Method - это два разных паттерна
Взять растения с разной хиральностью и вот борьба за солнечный свет
Пол Андерсон "Звездный торговец"
По моему личному опыту ИИ-тексты отличаются поразительно низким количеством полезной информации на единицу контента. Бывает читаешь, читаешь, вроде интересно, а что прочитал - непонятно. Три раза одну мысль перевернули по разному, досыпали несвязанных фактов, пропустили логические цепочки, никаких выводов или деталей, позволяющих эти выводы сделать самим. Конечно, так же пишут и некоторые копирайтеры, но это не в плюс к ним.
exec-кодогенерация не меняет подход к созданию объектов, она позволяет делать инайлнинг, вырезание веток и разворачивание циклов.
Условно, до кодгена был такой код
то, имея
cached=False, аdeps=[int, str, A], мы можем вырезать иф, убрать распаковку и сгенерироватьРезвол асинк зависимостей в dishka есть, то я бы рекомендовал с этим быть осторожнее. С большой вероятностью (вероятно не всегда), если вы делает async-вызов при создании ресурса, вы смешиваете бизнес логику и просто получение зависимости. При этом я понимаю, что избежать async вызова при финализации ресурса будет сложнее
Асинкио таску можно потом когда-нибудь заэвейтить и получить результат, а тут.. увы