&引用;获得“绑定”;方法在使用RoutingSession时在sqlalchemy中调用了两次

&引用;获得“绑定”;方法在使用RoutingSession时在sqlalchemy中调用了两次,session,sqlalchemy,bind,master-slave,Session,Sqlalchemy,Bind,Master Slave,我正在使用sqlalchemy的主/从,通过类似 engines = { 'master':create_engine("sqlite:///master.db"), 'other':create_engine("sqlite:///other.db"), 'slave1':create_engine("sqlite:///slave1.db"), 'slave2':create_engine("sqlite:///slave2.db"), } from sql

我正在使用sqlalchemy的主/从,通过类似

engines = {
    'master':create_engine("sqlite:///master.db"),
    'other':create_engine("sqlite:///other.db"),
    'slave1':create_engine("sqlite:///slave1.db"),
    'slave2':create_engine("sqlite:///slave2.db"),
}

from sqlalchemy.orm import Session, sessionmaker
import random

class RoutingSession(Session):
    def get_bind(self, mapper=None, clause=None):
        if mapper and issubclass(mapper.class_, MyOtherClass):
            return engines['other']
        elif self._flushing:
            return engines['master']
        else:
            return engines[
                random.choice(['slave1','slave2'])
            ]

我在“get_bind”方法中打印了日志。我发现“get_bind”方法在使用“session.add(r);session.commit()”时执行了两次。 那为什么要两次呢


使用“session.execute('insert…');session.commit()”时,“get_bind”方法仅被调用一次。

该会话支持多个引擎同时与之关联,并且这些引擎基于映射器或表与会话关联。因此,每当会话需要与数据库对话,并且它手头有一个特定的
mapper()
要处理时,它必须调用
get\u bind()
,以便找到这个特定映射器的正确引擎。在flush中,假设存在脏状态(session.add(r))的结果,一个特定的
mapper()
会被多次查询以准备发出SQL-目前至少有一次用于“save”过程,一次用于“delete”过程,尽管在这种情况下,我可以尝试改进不必要的抓取以进行删除(编辑:这已经完成)

通过粘贴
import-pdb,您总是可以知道为什么调用某个对象;pdb.在其中设置_trace()
,然后每次到达控制台时在控制台上执行“where”

因此,一般来说,您应该假设始终调用get_bind()。它应该不在乎多久被调用一次

编辑:0.8和0.7的最新提示在保存/删除过程中没有要刷新的状态时,不会调用get_bind(),因此现在在这个特定测试中只调用一次