Tortoise ORM 动态引入不同路径同名Model的报错

1,173 阅读1分钟

背景

在不同路径下,定义了同一个名称的DataModel,在动态import不同路径下DataModel查数据时,发现没有数据库关联模型的报错。。。

from tornado.util import import_object

async def query(model_path):
    object_ = import_object(model_path)
    DataModel = getattr(object_, "DataModel")
    data = await DataModel.filter().values()
    ...

报错

.venv\Lib\site-packages\tortoise\models.py

    @property
    def db(self) -> BaseDBAsyncClient:
        try:
            return current_transaction_map[self.default_connection].get()
        except KeyError:
            raise ConfigurationError("No DB associated to model")

报错行271raise ConfigurationError("No DB associated to model")

实际是这个self.default_connection变量为None造成的

但明明定义模型时已经指定了app啦,搞不懂。。。

调试跟踪

定位了所有对这个self.default_connection变量的定义的地方
找到这个文件
.venv\Lib\site-packages\tortoise\__init__.py

    for model in cls.apps[name].values():
        model._meta.default_connection = info.get("default_connection", "default")

注意看437行
按道理无论如何都会设置为"default"的

但观察了cls.apps变量后,发现里面存储了所有的model中只有一个DataModel。。。
石化吐血,那么多的DataModel去哪呢?
我还是老老实实的蠢办法给每个DataModel加个尾缀ID加以区分,
动态调用时,拼接DataModel{ID}出来。

挣扎尝试

在麻烦的调试前做的“努力”:
1、试了调用时手动指定,但莫得用。
2、也对那个变量所在类做了重载,也莫得用。
3、尝试了每次手动传递这个model,也不照。

解决方法

改名字保持Model唯一命名(尽管在不同路径)

回头想想

其实这个cls.apps变量去装载model时,有时候会装载到某个DataModel,就能查到数据,
也和执行的情况一致,即每次重新启动服务时,有时候能查到数据,有时候不行;
也想着去hub上题issue,想想没那个水平和脑子,还是用蠢版本,记录在这里,
交给下一位有缘人处理吧!