为什么使用RoutingSession时,SQLAlchemy Session.filter().update/delete会引发只读异常?

2024-10-03 00:19:22 发布

您现在位置:Python中文网/ 问答频道 /正文

下面是我的配置,slave是只读的:

engines = {                                                                        
    'master': create_engine(                                                       
        settings.MASTER_URL, echo=settings.ECHO_SQL, pool_recycle=3600),           
    'slave': create_engine(                                                        
        settings.SLAVE_URL, echo=settings.ECHO_SQL, pool_recycle=3600),            
}                                                                                  


class RoutingSession(Session):                                                     
    def get_bind(self, mapper=None, clause=None):                                  
        #return engines['master']                                                  
        if self._flushing:                                                         
            return engines['master']                                               
        else:                                                                      
            return engines['slave']                                                

DBSession = scoped_session(sessionmaker(class_=RoutingSession))

当我这样做的时候:

^{pr2}$

它引发了一个由于“只读”而无法删除的异常。在

如何重写我的路由会话,使上面的“删除”使用“master”数据库

---编辑1---

我做了更多的测试。上面的“delete”与下面的“delete”不同,RoutingSession将返回“master”:

model = s.query(Model).filter(Model.id == 1).first()
s.delete(model)
s.commit()

Tags: echomasterurlsqlreturnsettingscreatedelete
1条回答
网友
1楼 · 发布于 2024-10-03 00:19:22

query.delete()不是“flush”的一部分,因此通常如果您使用的是routing session recipe,那么您需要实现using_bind(),并在delete()等操作之前调用它:

class RoutingSession(Session):

    def get_bind(self, mapper=None, clause=None ):
        if self._name:
            return engines[self._name]
        else:
            # other cases here

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

然后使用:

^{pr2}$

相关问题 更多 >