Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django: multiple db and contenttype

Tags:

django

I am creating a Django project with one app called 'db_manager'. I would like to create two db: one for the db_manager models, and one for the core django models (auth, admin, contentTypes, session...)

First, I run the migrations to create the core models in the adw_core db. Then, I run the migrations to create the db_manager models in the adw_facts db. I use this command: python manage.py migrate db_manager --database adw_facts

I have a router set up that directs app to the appropriate db:

settings.py

DATABASE_ROUTERS = ['data_warehouse.db_routers.DatabaseRouter']

MAP_APPS_TO_DB = {
    'db_manager': 'adw_facts',
    'django.contrib.auth': 'adw_core',
    'django.contrib.sessions': 'adw_core',
}

db_routers.py

class DatabaseRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label in settings.MAP_APPS_TO_DB:
            return settings.MAP_APPS_TO_DB[model._meta.app_label]
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in settings.MAP_APPS_TO_DB:
            return settings.MAP_APPS_TO_DB[model._meta.app_label]
        return None

    def allow_relation(self, obj1, obj2, **hints):
        # Allow any relation between apps that use the same database.
        db_obj1 = settings.MAP_APPS_TO_DB.get(obj1._meta.app_label)
        db_obj2 = settings.MAP_APPS_TO_DB.get(obj2._meta.app_label)
        if db_obj1 and db_obj2:
            if db_obj1 == db_obj2:
                return True
            else:
                return False
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label in settings.MAP_APPS_TO_DB:
            return db == settings.MAP_APPS_TO_DB[app_label]
        return None

When I run the migrations to create the db_manager models in the adw_facts db, I get the following error:

RuntimeError: Error creating new content types. Please make sure contenttypes is migrated before trying to migrate apps individually.

I confirm that table 'core_db.django_content_type' exists. The problem must be that the django.contrib.contenttypes app is trying to create contentTypes for db_manager in adw_facts db but table core_db.django_content_type is in the adw_core db.

I don't want to delete the contenttypes app because I am using it with other Django functionalities.

I can think of the following solutions:

  1. disable contenttypes for the facts models

  2. create a secnod contenttypes table for the facts_db

Neither of these is very appealing. Please let me know if you have a better solution.


1 Answers

Just faced the same issue (on django 2.1). Based on the documentation mentioned by @Tony, it seems that you need to duplicate data from several django components in each database. Here's what worked for me:

def allow_migrate(self, db, app_label, model_name=None, **hints):
    if app_label in ('sites', 'contenttypes', 'auth'):
        return True

    if app_label in settings.MAP_APPS_TO_DB:
        return db == settings.MAP_APPS_TO_DB[app_label]
    return None
like image 173
Nielk Avatar answered Oct 22 '25 03:10

Nielk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!