3

I used two databases, one is default sqlite3 and another mysql. I just created a model Post under app named theapp. I have also created routers.py.

This is settings.py

DATABASES = {
    'default': {
       'ENGINE': 'django.db.backends.sqlite3',
       'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },

    'customer': {
       'NAME': 'customer',
       'ENGINE': 'django.db.backends.mysql',
       'USER': 'root',
       'PASSWORD': 'haha',
    }
 }

This is routers.py

class CustomerRouter:
"""
A router to control all database operations on models in the
auth application.
"""
def db_for_read(self, model, **hints):
    """
    Attempts to read auth models go to auth_db.
    """
    if model._meta.app_label == 'theapp':
        return 'customer'
    return None

def db_for_write(self, model, **hints):
    """
    Attempts to write auth models go to auth_db.
    """
    if model._meta.app_label == 'theapp':
        return 'customer'
    return None

def allow_relation(self, obj1, obj2, **hints):
    """
    Allow relations if a model in the auth app is involved.
    """        
    if obj1._meta.app_label == 'theapp' or \
       obj2._meta.app_label == 'theapp':
       return True
    return None

def allow_migrate(self, db, app_label, model_name=None, **hints):
    """
    Make sure the auth app only appears in the 'auth_db'
    database.
    """
    if app_label == 'theapp':
        return db == 'customer'
    return None

This is my models.py

from django.db import models
from django.utils import timezone


class Post(models.Model):
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    text = models.TextField()
    created_date = models.DateTimeField(
        default=timezone.now)
    published_date = models.DateTimeField(
        blank=True, null=True)

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title

This is what happening when I am trying to open posts table in admin panel

enter image description here

any ideas?

1
  • what software are you using on the lefthand side of the screen that lists 'versions', 'time', 'settings', etc? Commented Aug 22, 2018 at 17:13

3 Answers 3

3

I think you have not run migrations on your MySQL database,

Try

python manage.py migrate --database=customer

Read https://docs.djangoproject.com/en/1.11/ref/django-admin/#migrate

Sign up to request clarification or add additional context in comments.

2 Comments

database router will work, during your read and write operations but it will not work during migrate. So you need to run migrate on all your databases this is where --database option helps
I got this error django.utils.connection.ConnectionDoesNotExist: The connection 'db_name' doesn't exist.
2

In my case, I have two databases hosted on two different servers. Both databases worked with MySQL but it's the same thing than you with SQLLite-MySQL.

Maybe this example could solve your issue, so I display what I have into my Django Web Application.

Into my settings.py file something like that :

DATABASES = {

    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'default',
        'USER': 'osx',
        'PASSWORD': '******',
        'HOST': '172.30.10.12',
        'PORT': '3306',
        'OPTIONS': {
            'init_command': 'SET innodb_strict_mode=1',
            'sql_mode': 'traditional',
        }
    },


    'DS2': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'DS2',
        'USER': 'osx',
        'PASSWORD': '******',
        'HOST': '172.30.10.13',
        'PORT': '3306',
        'OPTIONS': {
            'init_command': 'SET innodb_strict_mode=1',
            'sql_mode': 'traditional',
        }
    }
}


BDD = ('default', 'DS2')
DATABASE_ROUTERS = ['MyApp.routersLocal.LocalRouter', 'MyApp.routersGlobal.GlobalRouter']

Then I have both files : routersGlobal.py and routersLocal.py :

#routersGlobal.py

from django.conf import settings

class GlobalRouter(object):
    """
A router to control all database operations on models in the
auth application.
"""

    def db_for_read(self, model, **hints):
        """
        Attempts to read auth models go to auth.
        """
        app_list = ('Identity',)

        if model._meta.app_label in app_list:
            return 'DS2'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write auth models go to auth.
        """
        app_list = ('Identity',)
        if model._meta.app_label in app_list:
            return 'DS2'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
        Allow relations if a model in the auth app is involved.
        """
        app_list = ('Identity',)
        if obj1._meta.app_label in app_list and obj2._meta.app_label in app_list:
            return 'DS2'
        return None

    def allow_migrate(self, db, app_label, model=None, **hints):
        """
        Make sure the auth app only appears in the 'auth'
        database.
        """
        app_list = ('Identity',)

        if app_label in app_list:
            return db == 'DS2'
        return None

and

#routersLocal.py
from django.conf import settings

class LocalRouter(object):
    """
A router to control all database operations on models in the
auth application.
"""

    def db_for_read(self, model, **hints):
        """
        Attempts to read auth models go to auth.
        """
        app_list = ('auth', 'admin', 'contenttypes', 'sessions', 'Configurations', 'log', 'Home', 'DSCORE', 'Informations')

        if model._meta.app_label in app_list:
            return 'default'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write auth models go to auth.
        """
        app_list = ('auth', 'admin', 'contenttypes', 'sessions', 'Configurations', 'log', 'Home', 'DSCORE', 'Informations')
        if model._meta.app_label in app_list:
            return 'default'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
        Allow relations if a model in the auth app is involved.
        """
        app_list = ('auth', 'admin', 'contenttypes', 'sessions', 'Configurations', 'log', 'Home', 'DSCORE', 'Informations')
        if obj1._meta.app_label in app_list and obj2._meta.app_label in app_list:
            return True
        return None

    def allow_migrate(self, db, app_label, model=None, **hints):
        """
        Make sure the auth app only appears in the 'auth'
        database.
        """
        app_list = ('auth', 'admin', 'contenttypes', 'sessions', 'Configurations', 'log', 'Home', 'DSCORE', 'Informations')

        if app_label in app_list:
            return db == 'default'
        return None 

EDIT :

Did you make makemigrations and migrate ?

6 Comments

Yes , I did migrate thing. Is 'Identity' the app that you choose to deal with DS2? And thanks , it is so good to study your code.
Identity is one of my Django application. Identity's data are stored in DS2. Other data coming from sessions, admin, auth .. are stored in my default database. That's why my default database corresponding to Local data and my DS2 database corresponding to Global. Some instance could be connected to DS2 in order to add data, get data ... but each instance has a local database (default in my case).
So you have to write routersLocal.py under project directory(outside of apps directory)?
I wrote both files in main directory (where settings.py are) and not module directory.
Oh I don't enter my edit with --database=yourbase .. :/ No I don't have a blog or a github. I'm just developping my Django Web App since 2 years now.
|
1

For some reason Django sometimes requires you to do

python manage.py makemigrations <application>

before

python manage.py migrate <application>

Make sure you delete the migrations and __pychache__ folders before you run the commands.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.