#34121 closed Bug (invalid)
Multi Databases documenation example doesn't work
Reported by: | Jan Przychodniak | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 4.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I have been following this documentation:
https://docs.djangoproject.com/en/4.1/topics/db/multi-db/
Here's my Router setup:
class AuthRouter: """ A router to control all database operations on models in the auth and contenttypes applications. """ route_app_labels = ('auth', 'contenttypes') TARGET_DB = 'users' def db_for_read(self, model, **hints): """ Attempts to read auth and contenttypes models go to auth_db. """ if model._meta.app_label in self.route_app_labels: return self.TARGET_DB return None def db_for_write(self, model, **hints): """ Attempts to write auth and contenttypes models go to auth_db. """ if model._meta.app_label in self.route_app_labels: return self.TARGET_DB return None def allow_relation(self, obj1, obj2, **hints): """ Allow relations if a model in the auth or contenttypes apps is involved. """ 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): """ Make sure the auth and contenttypes apps only appear in the 'auth_db' database. """ if app_label in self.route_app_labels: return db == self.TARGET_DB return None
Here are my settings (kept everything else default):
DATABASES = { 'default': { 'HOST': 'localhost', 'NAME': 'dev01', 'ENGINE': 'django.db.backends.postgresql', 'USER': 'postgres', 'PASSWORD': 'Admin123!', 'PORT': '5432', }, 'users': { 'HOST': 'localhost', 'NAME': 'dev01', 'ENGINE': 'django.db.backends.postgresql', 'USER': 'postgres', 'PASSWORD': 'Admin123!', 'PORT': '5433', } } DATABASE_ROUTERS = ['multidb.routers.AuthRouter']
Migrations are applied correctly on "users" database, however when attempting to apply them on default databse I get an error during Applying admin.0001_initial...Traceback (most recent call last):
Error states: django.db.utils.ProgrammingError: relation "django_content_type" does not exist
Well, logically so - such table is not present in this database. But I defined the router exactly as the documentation told me to. Therefore based on what I see in the documentation I labeled it as a bug in this report.
Change History (3)
comment:1 by , 2 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 2 years ago
It's documented on the same page:
"your routers must handle the names of all apps in INSTALLED_APPS before you migrate. See Behavior of contrib apps for information about contrib apps that must be together in one database."
It is, but I never reached this part, because I got stuck earlier in the example. When the docs asked me to:
With this setup installed, and all databases migrated as per Synchronizing your databases, lets run some Django code:
Which as far as I understand I need to perform migrations first to be able to run the code. Which migrations I cannot perform based on the example presented.
I would kindly suggest the example could be updated to mention that you need to include all the contrib apps in the same database before asking me to perform the migrations based on the example which never included an app like "django.contrib.admin" in the router.
Mind you, 'django.contrib.admin' is included in INSTALLED_APPS by default. I didn't change anything in the settings apart from the piece of code I sent here.
comment:3 by , 2 years ago
I would kindly suggest the example could be updated to mention that you need to include all the contrib apps in the same database before asking me to perform the migrations based on the example which never included an app like "django.contrib.admin" in the router.
This section already warns at the very beginning:
"Example purposes only!
This example is intended as a demonstration of how the router infrastructure can be used to alter database usage. It intentionally ignores some complex issues in order to demonstrate how routers are used.
This example won’t work if any of the models in myapp contain relationships to models outside of the other database. Cross-database relationships introduce referential integrity problems that Django can’t currently handle.
Of course, if you have a suggestion for clearer wording, please submit PR.
All contrib apps must be together in one database, as cross-database relations are not supported. It's documented on the same page: