Как правильно настроить пользовательскую модель User и несколько баз данных в Django?

Я создал пользовательское приложение для аутентификации пользователей и столкнулся с трудностями, чтобы заставить все работать с несколькими базами данных. Помощь была бы очень признательна.

В принципе, я создаю несколько проектов Django и хочу иметь уникальную базу данных для аутентификации и пользовательскую базу данных AUTH_USER_MODEL. Базы данных объявлены в settings.py с двумя маршрутизаторами, один для приложения auth, contenttypes и authentication, а другой маршрутизатор для остальных приложений.

Я успешно перенес пользовательскую модель User и создал createsuperuser с опцией --database=auth_db, но затем, когда я работаю в секции администратора и создаю объект в одном из моих приложений, Django выдает ошибку :

IntegrityError at /admin/django_celery_beat/crontabschedule/add/
insert or update on table "django_admin_log" violates foreign key constraint "django_admin_log_user_id_c564eba6_fk_authentication_user_id"
DETAIL:  Key (user_id)=(1) is not present in table "authentication_user".

Как вы можете видеть, он говорит, что пользователь с ID 1 не создан, но я вошел в систему и я на 100% уверен, что пользовательская модель User была создана в приложении authentication:

root@ec00652b9b9a:/app# python manage.py migrate authentication --database=auth_db
Operations to perform:
  Apply all migrations: authentication
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying authentication.0001_initial... OK

root@ec00652b9b9a:/app# python manage.py migrate contenttypes --database=auth_db
Operations to perform:
  Apply all migrations: contenttypes
Running migrations:
  No migrations to apply.

root@ec00652b9b9a:/app# python manage.py migrate auth --database=auth_db
Operations to perform:
  Apply all migrations: auth
Running migrations:
  No migrations to apply.

root@ec00652b9b9a:/app# python manage.py migrate admin --database=default
Operations to perform:
  Apply all migrations: admin
Running migrations:
  Applying admin.0001_initial... OK

root@ec00652b9b9a:/app# python manage.py migrate sessions --database=default
Operations to perform:
  Apply all migrations: sessions
Running migrations:
  Applying sessions.0001_initial... OK

Значит ли это, что Celery beat или admin ищет не в той базе данных? Как я могу исследовать эту проблему дальше?

databases_router.py

class AuthRouter:
    route_app_labels = {'auth', 'contenttypes', 'authentication'}

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'auth_db'
        return None

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'auth_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if (
            obj1._meta.app_label in self.route_app_labels or
            obj2._meta.app_label in self.route_app_labels
        ):
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label in self.route_app_labels:
            return db == 'auth_db'
        return None


class AppsRouter:

    def db_for_write(self, model, **hints):
        return 'default'

    def db_for_read(self, model, **hints):
        return 'default'

    def allow_relation(self, obj1, obj2, **hints):
        return True

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        return True

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': env("PROJECT_DB_NAME"),
        'HOST': env("PROJECT_DB_HOST"),
        'PORT': env("PROJECT_DB_PORT"),
        'USER': env("PROJECT_DB_USER"),
        'PASSWORD': env("PROJECT_DB_PASSWORD"),
        'OPTIONS': {'sslmode': 'require',
                    'options': '-c search_path=public'
                    },
    },
    'auth_db': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': env("AUTHENTICATION_DB_NAME"),
        'HOST': env("AUTHENTICATION_DB_HOST"),
        'USER': env("AUTHENTICATION_DB_USER"),
        'PORT': env("AUTHENTICATION_DB_PORT"),
        'PASSWORD': env("AUTHENTICATION_DB_PASSWORD"),
        'OPTIONS': {'sslmode': 'require',
                    'options': '-c search_path=public'
                    },
    },
}

DATABASE_ROUTERS = ['project.databases_router.AuthRouter', 'project.databases_router.AppsRouter']

AUTH_USER_MODEL = 'authentication.User'

Я не уверен насчет последних версий Django, но я не помню, чтобы Django (как и Postgres) мог обрабатывать отношения внешних ключей с другими базами данных (модель Django LogEntry полагается на одну)

Возможно, будет проще опустить админку Django и написать что-то самому, или подправить модель логирования.

Однако я бы пересмотрел ваше требование отделить пользователя от базы данных по умолчанию. Если вы действительно отделяете пользователя от контекстного приложения, вам, вероятно, не стоит полагаться на какие-либо внешние ключи для данных, связанных с пользователем.

Вернуться на верх