I created a custom application to authenticate users and have hard times to make everything work with multiple databases. Help would be much appreciated.
Basically, I create multiple Django projects and want a unique database for authentication and a custom AUTH_USER_MODEL. The databases are declared in settings.py with two routers, one for the auth, contenttypes, and authentication application, and the other router for the rest of the applications.
I successfuly migrated the custom User model and created createsuperuser with the option --database=auth_db but then, when I work in the admin section an create an object in one of my applications Django throws an error :
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".
As you can see, it says the user with ID 1 isn't created, but I'm logged with it and I'm 100% sure the custom User model was created in the authentication app:
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
Does it means Celery beat or admin is looking in the wrong database ? How could I investigate the issue further more ?
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'