【问题标题】:In Django, can I specify database when creating an object?在 Django 中,我可以在创建对象时指定数据库吗?
【发布时间】:2016-01-05 18:53:43
【问题描述】:

看看这个 Django ORM 代码:

my_instance = MyModel()
my_instance.some_related_object = OtherModel.objects.using('other_db').get(id)

此时,在第二行,Django会抛出错误:

ValueError: Cannont assign "<OtherModel: ID>": instance is on database "default", value is on database "other_db"

对我来说,这没有多大意义。如果我还没打过电话,Django 如何判断 my_instance 是哪个数据库:

my_instance.save(using='some_database')

还没有?

我猜,在构建对象期间,Django 会自动将其分配给default 数据库。我可以改变它吗?我可以在创建对象时通过将参数传递给其构造函数来指定数据库吗?根据文档,在创建对象时,我可以传递的唯一参数是其字段的值。那么我该如何解决我的问题呢?

在 Django 1.8 有一个名为 Model.from_db (https://docs.djangoproject.com/en/1.8/ref/models/instances/) 的新方法,但我使用的是早期版本的 Django,无法切换到现在更新了。查看实现它所做的只是设置两个模型的属性:

instance._state.adding = False
instance._state.db = db

那么将我的代码更改为:

my_instance = MyModel()
my_instance._state.adding = False
my_instance._state.db = 'other_db'
my_instance.some_related_object = OtherModel.objects.using('other_db').get(id)

还是因为这些标志在构造函数中使用而只能在构造函数中设置而为时已晚?

【问题讨论】:

    标签: python django orm django-orm django-database


    【解决方案1】:

    您可能想查看database routing,它从 Django 1.2 开始就受支持。这将允许您为不同的模型设置多个数据库(或“路由器”)。

    您可以创建自定义数据库路由器(继承自内置 object 类型的类),使用返回数据库名称的 db_for_readdb_for_write 方法(在 DATABASES 设置中定义) 应该用于传递给该方法的模型。返回 None 让 Django 弄清楚。

    它通常用于处理主从复制,因此您可以拥有一个与可写数据库分开的只读数据库,但同样的逻辑也适用于让您指定某些模型存在于某些数据库中。

    您可能还想定义一个allow_syncdb 方法,这样只有您希望出现在数据库 B 中的模型才会出现在那里,而其他所有模型都会出现在数据库 A 中。

    【讨论】:

      【解决方案2】:

      Django 知道每个对象来自哪个数据库,因为它在其内部属性中对此进行了说明。 QuerySet 自身也存储了这些信息。

      实际上,这里并不需要数据库路由来实现您想要的。

      考虑以下代码片段:

      my_instance = MyModel()
      my_instance.some_related_object_id = OtherModel.objects.using('other_db').get(id).id
      

      请注意我如何只分配 ID,而不是对象本身。

      您将在此处丢失实际对象,但获得存储参考数据的能力。

      AFAIK 没有 API 可以更改对象的关联数据库。

      【讨论】:

        猜你喜欢
        • 2010-11-07
        • 1970-01-01
        • 1970-01-01
        • 2011-07-24
        • 1970-01-01
        • 2014-05-06
        • 1970-01-01
        • 1970-01-01
        • 2019-06-03
        相关资源
        最近更新 更多