在Django中,我可以在创建对象时指定数据库吗?

mno*_*tka 5 python django orm django-orm django-database

看看这个 Django ORM 代码:

my_instance = MyModel()
my_instance.some_related_object = OtherModel.objects.using('other_db').get(id)
Run Code Online (Sandbox Code Playgroud)

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

ValueError: Cannont assign "<OtherModel: ID>": instance is on database "default", value is on database "other_db"
Run Code Online (Sandbox Code Playgroud)

对我来说,这没有多大意义。my_instance如果我什至没有调用,Django 如何知道哪个数据库是:

my_instance.save(using='some_database')
Run Code Online (Sandbox Code Playgroud)

然而?

我猜想,在构造对象期间,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
Run Code Online (Sandbox Code Playgroud)

那么将我的代码更改为:

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)
Run Code Online (Sandbox Code Playgroud)

或者现在这样做已经太晚了,因为这些标志在构造函数中使用并且必须仅在构造函数中设置?

Ste*_*man 1

您可能想研究一下数据库路由,它从 Django 1.2 起就受到支持。这将允许您为不同的模型设置多个数据库(或“路由器”)。

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

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

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