• Как заменить дескриптор __get__ метода класса?

    @oslik_ppc Автор вопроса
    Vindicar, на самом деле просто из интереса, как работает внутри Python, до этого момента все как-то логично вытекало)

    Алан Гибизов, тут просто замена этого метода, интересно чуть глубже, заменить __get__, который вызывается классом О_О
  • Есть ли разница между asyncsession.begin() и session.commit()?

    @oslik_ppc Автор вопроса
    Загир Меджидов, так и сделал, мне помог Ваш ответ, но просто для ясности, можно еще подсказку по надобности commit():

    Если sessionmaker() через __call__ возвращает объект AssyncSession, то он сам по себе context-manager, при выходе из него он просто закрывает сессию:

    #CODE: class AsyncSession(ReversibleProxy[Session]):
    
        async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None:
            task = asyncio.create_task(self.close())
            await asyncio.shield(task)


    Но вот его метод begin() как раз возвращает AsyncSessionTransaction (как вы и сказали, начинает транзакцию):
    #CODE: class AsyncSession(ReversibleProxy[Session]):
        def begin(self) -> AsyncSessionTransaction:
            """Return an :class:`_asyncio.AsyncSessionTransaction` object.
    
            The underlying :class:`_orm.Session` will perform the
            "begin" action when the :class:`_asyncio.AsyncSessionTransaction`
            object is entered::
    
                async with async_session.begin():
                    # .. ORM transaction is begun
    
            Note that database IO will not normally occur when the session-level
            transaction is begun, as database transactions begin on an
            on-demand basis.  However, the begin block is async to accommodate
            for a :meth:`_orm.SessionEvents.after_transaction_create`
            event hook that may perform IO.
    
            For a general description of ORM begin, see
            :meth:`_orm.Session.begin`.
    
            """
    
            return AsyncSessionTransaction(self)


    Но на выходе из контекста:
    # CODE: class AsyncSessionTransaction
        async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None:
            await greenlet_spawn(
                self._sync_transaction().__exit__, type_, value, traceback
            )


    Который как раз делает commit() (ну, старается или rollback())

    def __exit__(self, type_: Any, value: Any, traceback: Any) -> None:
            subject = getattr(self, "_trans_subject", None)
    
            # simplistically we could assume that
            # "subject._trans_context_manager is self".  However, any calling
            # code that is manipulating __exit__ directly would break this
            # assumption.  alembic context manager
            # is an example of partial use that just calls __exit__ and
            # not __enter__ at the moment.  it's safe to assume this is being done
            # in the wild also
            out_of_band_exit = (
                subject is None or subject._trans_context_manager is not self
            )
    
            if type_ is None and self._transaction_is_active():
                try:
                    self.commit()
                except:
                    with util.safe_reraise():
                        if self._rollback_can_be_called():
                            self.rollback()
                finally:
                    if not out_of_band_exit:
                        assert subject is not None
                        subject._trans_context_manager = self._outer_trans_ctx
                    self._trans_subject = self._outer_trans_ctx = None
  • Есть ли разница между asyncsession.begin() и session.commit()?

    @oslik_ppc Автор вопроса
    Загир Меджидов, понял, спасибо! Просто в документации как-то все расплывчато, например в исходниках begin():

    def begin(self) -> _AsyncSessionContextManager[_AS]:
            """Produce a context manager that both provides a new
            :class:`_orm.AsyncSession` as well as a transaction that commits.
    
    
            e.g.::
    
                async def main():
                    Session = async_sessionmaker(some_engine)
    
                    async with Session.begin() as session:
                        session.add(some_object)
    
                    # commits transaction, closes session
    
    
            """
    
            session = self()
            return session._maker_context_manager()


    Указывается, что на выходе из менеджера происходит commit()
  • Есть ли разница между asyncsession.begin() и session.commit()?

    @oslik_ppc Автор вопроса
    Но у ContextManager сессии, есть транзакции и в TransactionalContext в __exit__
    def __exit__(self, type_: Any, value: Any, traceback: Any) -> None:
            subject = getattr(self, "_trans_subject", None)
    
            # simplistically we could assume that
            # "subject._trans_context_manager is self".  However, any calling
            # code that is manipulating __exit__ directly would break this
            # assumption.  alembic context manager
            # is an example of partial use that just calls __exit__ and
            # not __enter__ at the moment.  it's safe to assume this is being done
            # in the wild also
            out_of_band_exit = (
                subject is None or subject._trans_context_manager is not self
            )
    
            if type_ is None and self._transaction_is_active():
                try:
                    self.commit()
    ...................


    Получается, при выходе из контекста он пытается сделать commit(), и вроде как доп вызов - избыточен, разве нет?
  • SQLAlchemy Модели для двух проектов?

    @oslik_ppc Автор вопроса
    shurshur, спасибо за ответ! Вопрос еще один: полное дублирование кода между проектами считается окей?:)
  • SQLAlchemy Модели для двух проектов?

    @oslik_ppc Автор вопроса
    shurshur, получается, в приложении fastapi будет пакет db для админ панели, и аналогичный для самого бота?
  • SQLAlchemy Модели для двух проектов?

    @oslik_ppc Автор вопроса
    Модератор, просто синхронизация между aiogram fastapi с sqlalchemy, вот и теги стояли ;)