Hi David Your router isn't configured correctly. This applies to all the allow_foo() methods, but see allow_migrate [1] as an example:
Determine if the migration operation is allowed to run on the database with alias db. Return True if the operation should run, False if it shouldn’t run, or None if the router has no opinion. Your routers *should* be having an opinion about whether that app/model can be migrated on a specific database! For instance, you say "the last app" should stay only on validations, but what your ValidationRouter says is "If the app label is called fourth_model, run migrations on this database", but it never checks what the database is. For ValidationRouter.allow_migrate you probably want something like this: def allow_migrate(self, ...): if app_label == "fourth_model": return db == "validations" elif db == "validations": return False EG: * if the app label is an app that should be in the validations DB, allow migrate when the db is the validations DB * if it isn't and the DB is the validations DB, don't allow migrations to it * if neither of those things, this router doesn't care. Similarly, for allow_relations() you should be returning False when the models should not be related. Incidentally, all python functions return None if the end of the function is reached without an explicit return value, so you never have to end your functions with an explicit "return None". Cheers Tom [1] https://docs.djangoproject.com/en/2.1/topics/db/multi-db/#allow_migrate On Tue, Oct 30, 2018 at 10:09 AM David Lubomirov <davidlubomi...@gmail.com> wrote: > > Hello, > > In my project I have 3 applications, and I'm trying to split them across 2 > databases. > > More specifically 2 of the apps and Django "auth" application should work > with the first database, > and the last application should remain in the second database. > > These are the DB settings: > > DATABASE_ROUTERS = [ > '<PATH_TO_ROUTER>.PrimaryRouter', > '<PATH_TO_ROUTER>.ValidationRouter' > ] > > DATABASES = { > 'default': {}, > 'primary': { > 'NAME': 'primary', > 'ENGINE': 'django.db.backends.postgresql', > 'USER': '<DB_USER>', > 'PASSWORD': '<DB_PASS>', > 'HOST': 'localhost', > }, > 'validations': { > 'NAME': 'validations', > 'ENGINE': 'django.db.backends.postgresql', > 'USER': '<DB_USER>', > 'PASSWORD': '<DB_PASS>', > 'HOST': 'localhost', > } > } > > Therefore these are the class routers: > > class PrimaryRouter: > """ > Router to control all database operations for the following applications: > - first_model > - second_model > - auth > """ > def db_for_read(self, model, **hints): > if model._meta.app_label == 'auth' or \ > model._meta.app_label == 'first_model' or \ > model._meta.app_label == 'second_model': > > return 'primary' > > return None > > def db_for_write(self, model, **hints): > if model._meta.app_label == 'auth' or \ > model._meta.app_label == 'first_model' or \ > model._meta.app_label == 'second_model': > > return 'primary' > > return None > > def allow_relation(self, first_object, second_object, **hints): > if first_object._meta.app_label == 'auth' or \ > second_object._meta.app_label == 'auth': > > return True > > if first_object._meta.app_label == 'first_model' or \ > second_object._meta.app_label == 'first_model': > > return True > > if first_object._meta.app_label == 'second_model' or \ > second_object._meta.app_label == 'second_model': > > return True > > return None > > def allow_migrate(self, db, app_label, model_name=None, **hints): > if app_label == 'auth' or \ > app_label == 'first_model' or \ > app_label == 'second_model': > > return db == 'primary' > > return None > > > class ValidationRouter: > """ > Router to control all database operations for the following applications: > - fourth_model > """ > def db_for_read(self, model, **hints): > if model._meta.app_label == 'fourth_model': > return 'validations' > > return None > > def db_for_write(self, model, **hints): > if model._meta.app_label == 'fourth_model': > return 'validations' > > return None > > def allow_relation(self, first_object, second_object, **hints): > if first_object._meta.app_label == 'fourth_model' or \ > second_object._meta.app_label == 'fourth_model': > return True > > return None > > def allow_migrate(self, db, app_label, model_name=None, **hints): > if app_label == 'fourth_model': > return True > > return None > > > When I run migration on the first database "primary", everything is working. > But on the second database I'm getting the following exception: > > > django.db.utils.ProgrammingError: relation "auth_user" does not exist > > > The question - do I need to also specify the "auth" Django application in the > second DB router "validations", > or there's something wrong with my setup ? > > According to Django docs for version 2.1, this kind of setup is working - > https://docs.djangoproject.com/en/2.1/topics/db/multi-db/ . > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-users+unsubscr...@googlegroups.com. > To post to this group, send email to django-users@googlegroups.com. > Visit this group at https://groups.google.com/group/django-users. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-users/8eef7cfe-93ed-4322-ab84-09261e27f460%40googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To post to this group, send email to django-users@googlegroups.com. Visit this group at https://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAFHbX1%2BOnVbc0%2BOGGvypGYcbDwum6azTwVg6fzgp%3D%3Dc79yqtzQ%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.