0

我正在尝试为我的 django 应用程序设置两个数据库。第一个用于用户,第二个用于任何类型的用户内容。该应用程序通过 docker compose 进行了 docker 化。

这是 docker-compose.yaml 文件

version: '3'

services:
  postgres:
    image: postgres:latest
    environment:
      - POSTGRES_PASSWORD=test
    ports:
      - "5432:5432"
    restart: always
  mongodb:
    image: mongo:latest
    command: ["--bind_ip_all"]
    ports:
      - "27017:27017"
    restart: always
  django:
    build: .
    command: bash -c "
        python service_platform/manage.py makemigrations &&
        python service_platform/manage.py migrate &&
        python service_platform/manage.py runserver 0.0.0.0:8000
      "
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - postgres
      - mongodb
    links:
      - postgres
      - mongodb

下面是django的settings.py的db设置

DATABASE_ROUTERS = [
    'content_manager.content_db_router.ContentDBRouter',
]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'HOST': 'postgres',
        'PASSWORD': 'test',
        'PORT': 5432,
    },
    'content': {
        'ENGINE': 'djongo',
        'NAME': 'mongodb',
        'CLIENT': {
            'host': 'mongodb',
            'port': 27017,
        },

    }
}

这是我写的自定义路由器

class ContentDBRouter(object):

    content_db = 'content'
    default_db = 'default'

    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'content_manager':
            return self.content_db
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'content_manager':
            return self.content_db
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if db == self.content_db:
            return True
        elif db == self.default_db:
            return True
        else:
            raise Exception(f'DB with id {db} not found!')

最后这是我想要迁移到 mongo db 的模型

class Post(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.TextField(default='default title')

当我尝试将帖子插入数据库时​​,我在浏览器中出现以下错误

MigrationError at /
Table content_manager_post does not exist in database

以及在使用 dbs 和 django 应用程序运行容器的终端中出现以下错误。

raise MigrationError(f'Table {collection} does not exist in database')

我能否获得一些帮助来正确配置 mongo 和 postgres 以便使用它们。最初,我尝试在没有默认数据库和自定义路由器的情况下为我拥有的每个模型运行应用程序,但随后恢复到此状态以正确配置一个非默认数据库。我还尝试清除整个 docker 卷和迁移并从头开始运行它以应用迁移,但我仍然没有设法让它工作。

4

1 回答 1

-2

您好要使用两个数据库,您需要这个。有关 Django Read Documents 中多个数据库的更多信息。 https://docs.djangoproject.com/en/3.0/topics/db/multi-db/ 如果我的回答很好且有帮助,请选择回答

DATABASES = {
'default': {},
'users': {
    'NAME': 'user_data',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_user',
    'PASSWORD': 'superS3cret'
},
'customers': {
    'NAME': 'customer_data',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_cust',
    'PASSWORD': 'veryPriv@ate'
}
}

同步你的数据库¶ 迁移管理命令一次在一个数据库上运行。默认情况下,它在默认数据库上运行,但通过提供 --database 选项,您可以告诉它同步不同的数据库。因此,要将所有模型同步到上面第一个示例中的所有数据库,您需要调用:

$ ./manage.py migrate
$ ./manage.py migrate --database=users

如果您不希望每个应用程序都同步到特定数据库上,则可以定义一个数据库路由器,该路由器实施限制特定模型可用性的策略。

如果像上面第二个示例一样,您将默认数据库留空,则必须在每次运行 migrate 时提供数据库名称。省略数据库名称会引发错误。对于第二个例子:

$ ./manage.py migrate --database=users
$ ./manage.py migrate --database=customers
于 2020-03-23T20:04:21.887 回答