另一个数据库中的 Django 外键

Django Foreign key in another database

我有两个独立的 Django 应用程序和两个不同的数据库。在 APP1 中,我需要 APP2 数据库中一个 table 中的所有记录。除此之外,我的一个 APP1 模型有一个指向 APP2 模型的外键,根据文档,这是不可能的。

由于 Django 不支持跨多个数据库的外键关系,我不知道该怎么做。

官方文档:

If you have used a router to partition models to different databases, any foreign key and many-to-many relationships defined by those models must be internal to a single database.

This is because of referential integrity. In order to maintain a relationship between two objects, Django needs to know that the primary key of the related object is valid. If the primary key is stored on a separate database, it’s not possible to easily evaluate the validity of a primary key.

作为一种解决方案,我想到了合并这两个数据库,这样这两个应用程序就可以使用同一个数据库。但是那样的话我会把模型弄得一团糟,因为 APP1 只需要来自 APP2 的一个 table,它不需要剩余的模型和 DB table。另外,我很确定从这两个应用程序迁移到同一个数据库时会出现问题(冲突)。

我正在使用 Django DB 路由器,这是我迄今为止尝试过的方法:

class Car(models.Model):
    _DATABASE = "cars"
    color = models.TextField(max_length=1000)
    ...

class Employee(models.Model):
    id = models.IntegerField()
    car = models.ForeignKey(Car)
    ...

它给了我:

django.db.utils.OperationalError: (1054, "Unknow column 'car' in 'employees'")

我认为这个问题与 django 无关。按照设计,DBMS 不允许数据库之间的 FK。也许您可以在 Internet 上找到一些解决方法,但它们可能不遵守最佳实践。

检查跨数据库关系部分: https://docs.djangoproject.com/en/3.2/topics/db/multi-db/

一个 DB 还是两个?

第一个问自己的问题是否真的有必要拥有两个不同的数据库?多个应用程序使用同一个数据库在 PHP 世界中很常见,因为大多数人都使用共享主机并且主机计划只允许一个数据库。

网站很少有足够的流量来将内容拆分到两个数据库中。通常路由器的开销使得它不值得。使用专门的软件几乎总是可以更好地处理分片。

是的,必须是两个!

这不是不可能,只是太难了。

首先要做的是改变你的Car模型

class Car(models.Model):
    color = models.TextField(max_length=1000)
    class Meta:
        managed = False

请注意,它不再引用第二个数据库并且它是非托管的。但是您的数据库中没有这样的 table 。所以你需要create a view

 CREATE OR REPLACE VIEW myapp_cars AS SELECT * FROM cars.otherapp_cars

请确保使用准确的数据库和 table 名称以匹配您现有的名称。我们只完成了一半。您需要创建一个触发器以插入到其他数据库中。这个之前已经讨论过很多次了,我就不多说了。例子

  1. MySQL Trigger to insert data into different DB
  2. How to create trigger to insert data to a database on another server

如果您希望这些步骤可重现,您将需要手动添加迁移。