从django中具有相同表名的多个数据库中获取数据

时间:2017-12-11 10:06:45

标签: python mysql django database

我需要从Django中的不同导入的MySQL数据库中获取数据 (Django 1.11.7,Python 3.5.2)。 我运行manage.py inspectdb --database '<db>'然后使用django中的模型。

到现在为止,我只需访问具有不同名称的表。为此,我在查询集中使用using关键字来指定适当的数据库,然后连接结果,如下所示:

from ..models.db1 import Members
from ..models.db2 import Actor

context['db1_data'] = Members.objects.using('db1').filter...
context['db2_data'] = Actor.objects.using('db1').filter...

context["member_list"] = list(chain(
    context["db1_data"],
    context["db2_data"],
))

return context

现在我遇到的问题是两个数据库中存在具有相同型号名称的表。使用上述方法时我得到以下错误(我替换了名称):

RuntimeError: Conflicting '<table-name>' models in application '<app>': <class '<app>.<subfolder>.models.<db1>.<table-name>'> and <class '<app>.<subfolder>.models.<db2>.<table-name>'>.

我已尝试使用其他名称导入模型,如下所示:

from ..models.db3 import Members as OtherMembers

但错误仍然存​​在。

不应该from ..models.db1from ..models.db2足够明确让Django发现两个模型之间的区别吗?

一个选项可能是重命名模型本身,但这意味着重命名具有相同名称的每个数据库模型。由于我将来会使用更多的数据库,这对我来说不是一个选择。

我尝试from models import db1, db2然后db1.Members等等,这仍然会引发错误。

我读到了关于元db_table = 'dbname.tablename' - 选项,但由于该模型是通过inspectdb自动生成的,因此每个类都已经有类似的内容:

class MyModel(models.Model):
    <models>

    class Meta:
        managed = False
        db_table = 'my_model'

如前所述,其他数据库具有完全相同的模型,因此具有相同的Meta类。我不能也不想改变每个Meta课程。

修改

我的项目结构如下:

app
    -> admin.py
    -> ...
    -> models.py
    -> views.py
    subfolder
        -> models
            -> db1.py
            -> db2.py
        -> views
            -> db1.py
            -> db2.py

2 个答案:

答案 0 :(得分:2)

假设您已设置multiple databases correctly

  1. 您是否尝试过添加Custom Router
    如果不遵循文档链接中给出的示例。

  2. 您是否曾尝试为模型使用Custom Manager

    为每个模型创建一个管理器,如下所示:

    class YourModelManagerX(models.Manager):
        def get_queryset(self, *args, **kwargs):
            return super().get_queryset(*args, **kwargs).using('your_db_X')
    

    然后将其作为objects字段添加到相应的模型中:

    class YourModel(models.Model):
        ...
        fields
        ...
        objects = YourManagerX()
    
        class Meta:
            managed = False
    
  3. 您可能需要同时尝试这两种方式。

答案 1 :(得分:1)

如果db1.Members和db3.Members具有相同的定义,则不必为每个数据库单独重新声明Members类。

Models.py

...
class Members(models.Model): # Only declared once ever!
    ....

然后,

from Models import Members

context['db1_data'] = Members.objects.using('db1').filter...
context['db3_data'] = Members.objects.using('db3').filter...

... # continue processing
  

不应该从..models.db1和..models.db2中清楚地看到django能够发现两个模型之间的区别吗?

Django模型不是特定于数据库的,更像是特定于模式的,所以如果在两个不同的数据库中有相同的表,则扩展model.Models的一个类就足够了。然后,当您尝试检索对象时,使用using()指定数据库,或使用路由器,您可以在Django docs https://docs.djangoproject.com/en/2.0/topics/db/multi-db/#an-example

中阅读这些路由器。