Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Multiple Databases But Auth In Single Db

Tags:

python

django

So I have a Django project with couple of databases:

default
login
foo
bar

Each app has it's own database (for example login app will store all models in login database etc).

I want to store all Django Admin related models such as permissions, users, groups in the default database. This is how my router looks:

class DBRouter(object):
    default_db_apps = (
        'auth',
        'admin',
        'contenttypes',
        'sessions',
    )

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.default_db_apps:
            return 'default'
        return model._meta.app_label

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.default_db_apps:
            return 'default'
        return model._meta.app_label

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

    def allow_syncdb(self, db, model):
        if model._meta.app_label in self.default_db_apps:
            return db == 'default'
        return False

When I run:

python manage.py syncdb --noinput

It creates all auth related tables in the default database which is correct. When I look into auth_permissions table though, there are missing permissions for other apps. For example:

defaultdb=# select * from auth_permission;
 id |          name           | content_type_id |      codename      
----+-------------------------+-----------------+--------------------
  1 | Can add log entry       |               1 | add_logentry
  2 | Can change log entry    |               1 | change_logentry
  3 | Can delete log entry    |               1 | delete_logentry
  4 | Can add permission      |               2 | add_permission
  5 | Can change permission   |               2 | change_permission
  6 | Can delete permission   |               2 | delete_permission
  7 | Can add group           |               3 | add_group
  8 | Can change group        |               3 | change_group
  9 | Can delete group        |               3 | delete_group
 10 | Can add user            |               4 | add_user
 11 | Can change user         |               4 | change_user
 12 | Can delete user         |               4 | delete_user
 13 | Can add content type    |               5 | add_contenttype
 14 | Can change content type |               5 | change_contenttype
 15 | Can delete content type |               5 | delete_contenttype
 16 | Can add session         |               6 | add_session
 17 | Can change session      |               6 | change_session
 18 | Can delete session      |               6 | delete_session
(18 rows)

I would like permissions to all models (even models in different databases) to be stored in the default app.

Any solution for this?

like image 306
Richard Knop Avatar asked Oct 21 '22 16:10

Richard Knop


1 Answers

The thing is that Permissions use foreign keys (generic foreign keys with ContentTypes if I remember well), and foreign keys between two databases are not supported!

See this post Django - multiple databases and auth.Permission

You can also read the limitation of multiple databases from Django documentation.

A few quotes:

Django doesn’t currently provide any support for foreign key or many-to-many relationships spanning multiple databases.

Several contrib apps include models, and some apps depend on others. Since cross-database relationships are impossible, this creates some restrictions on how you can split these models across databases:
- each one of contenttypes.ContentType, sessions.Session and sites.Site can be stored in any database, given a suitable router.
- auth models — User, Group and Permission — are linked together and linked to ContentType, so they must be stored in the same database as ContentType.

like image 85
pawamoy Avatar answered Oct 23 '22 11:10

pawamoy