0

I'm trying to demonstrate the use of multi-database in Django using db routers but facing issues dumping data into respective databases. The django models are visible in both databases, but not my own created ones.

Here is my models.py file:

from django.db import models
from django.db import models
from django.contrib.auth.models import User
from peewee import * 
import psycopg2


# Create your models here.
class temp(models.Model):
    id= models.IntegerField(primary_key=True) 
    class Meta:
        app_label='client_db'
        db_table='temp'

class temp2(models.Model):
    id= models.IntegerField(primary_key=True) 
    class Meta:
        app_label='default'
        db_table='temp2'

settings.py

DATABASE_ROUTERS = ('app_celery.dbrouter.client_router',
                   )
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
    ,
     'client_db': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'amm',
        'USER': 'xxxx',
        'PASSWORD': 'xxxx',
        'HOST': '127.0.0.1',
        'PORT': 5432,
    },
}

dbrouter.py


class client_router:
    """
    A router to control all database operations on models in the
    user application.
    """
    def db_for_read(self, model, **hints):
        """
        Attempts to read user models go to users_db.
        """
        if model._meta.app_label == 'client_db':
            return 'client_db'
        return 'default'

    def db_for_write(self, model, **hints):
        """
        Attempts to write user models go to users_db.
        """
        if model._meta.app_label == 'client_db':
            return 'client_db'
        return 'default'

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

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

My migrations run successfully as follows:

python3 manage.py makemigrations     
python3 manage.py migrate
python3 manage.py migrate --database=client_db

Both of my tables only display django models and not my own. Similarly for db.sqlite3 too. I'm sure there's some silly change I need to make, but not quite sure what it is. Please do help me out. Thanks

enter image description here

2 Answers2

2

The app_label is used only if a model is outside a Django app, I believe it's not your case https://docs.djangoproject.com/en/4.2/ref/models/options/#app-label

All you need to do is:

Remove app_label from your models and run

$ python manage.py makemigrations
$ python manage.py migrate

Some important tips:

You don't need to add id field on models because a model inherits id from models.Model (Unless you want to change it's behaviour)(https://docs.djangoproject.com/en/4.2/topics/db/models/#quick-example)

A python class name must be wrote as CamelCase according to https://peps.python.org/pep-0008/#descriptive-naming-styles

Diego Magalhães
  • 1,704
  • 9
  • 14
0
route_app_labels = {'app_name'} # name of my app

Needs to be given in router which is the name of my app, and all those models will go in that database.

app_label is not needed. As suggested by @Diego