1

最近、SQLAlchemyInvalidRequestErrorが発生しました。エラーログには次の情報が表示されます。

InvalidRequestError: Transaction <sqlalchemy.orm.session.SessionTransaction object at
0x106830dd0> is not on the active transaction list

どのような状況でこのエラーが発生しますか?

- - -編集 - -

# the following two line actually in my decorator
s = Session()
s.add(model1)

# refer to <http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/>
s2 = Session().using_bind('master')

model2 = s2.query(Model2).with_lockmode('update').get(1)
model2.somecolumn = 'new'

s2.commit() 

この例外が発生します

-----編集2-----

s = Session().using_bind('master')


model = Model(user_id=123456)
s.add(model)
s.flush() 
# here, raise the exception. 
# I add log in get_bind() of RoutingSession. when doing 'flush', the _name is None, and it returns engines['slave'].  
#If I use commit() instead of flush(), then it commits successfully

using_bindメソッドを次のように変更すると、うまく機能します。

def using_bind(self, name):
    self._name = name
    return self

前のRoutingSession:

class RoutingSession(Session):
    _name = None                                                                                                                                                

    def get_bind(self, mapper=None, clause=None):   
        logger.info(self._name)         
        if self._name:                                                                           
            return engines[self._name]                                          
        elif self._flushing:                                                                                                                                                                                                                  
            logger.info('master')                                                  
            return engines['master']                                               
        else:                                                                      
            logger.info('slave')    
            return engines['slave']

    def using_bind(self, name):                              
        s = RoutingSession()                                                      
        vars(s).update(vars(self))   
        s._name = name                                                                    
        return s
4

1 に答える 1

2

これは、決して発生してはならない内部主張です。セッションを並行して不適切に使用している、またはその内部を操作している可能性がある場合は、少なくとも完全なスタック トレースがなければ、この質問に答える方法はありません。セッション オブジェクトに関連するプライベート メソッドまたは状態を操作した場合に発生する例外のみを示すことができます。

これがそれです:

from sqlalchemy.orm import Session

s = Session()
s2 = Session()

t = s.transaction
t2 = s2.transaction

s2.transaction = t   # nonsensical assignment of the SessionTransaction
                     # from one Session to also be referred to by another,
                     # corrupts the transaction chain by leaving out "t2".
                     # ".transaction" should never be assigned to on the outside

t2.rollback()  # triggers the assertion case

基本的に、「.transaction」に割り当てることは想定されていないため、上記は決して発生しないはずです。これは読み取り専用属性です。

于 2012-12-21T05:37:44.850 に答える