Skip to content

Instantly share code, notes, and snippets.

@buddylindsey
Created January 22, 2019 21:32
Show Gist options
  • Select an option

  • Save buddylindsey/78f313c5144513a2919b340107e681ea to your computer and use it in GitHub Desktop.

Select an option

Save buddylindsey/78f313c5144513a2919b340107e681ea to your computer and use it in GitHub Desktop.
Possible Bug with Multi-db in django 2.1

Steps to re-produce a possible bug in using multiple databases in Django 2.1

Goal

The goal is to be able to have an app that all models in that app go to a seperate database, other models like the django-admin, go to default.

Expected

I expect that when I target no database it migrates all existing migrations, not in my new app, to the default database connection.

Then when I run ./manage.py migrate --database=otherdatabase it only migrates those models in the new app, or none at all.

This could be a flawed expectation, but it is my understanding of what should happen.

What is happening

No matter what database I use when doing a ./manage.py migrate it is migrating all tables to the database.

Steps to reproduce

  1. Install create virtualen environment
  2. Setup a postgres database. I am doing this throud docker
version: "3"

services:
  db:
    image: postgres:10.1-alpine
    environment:
      POSTGRES_DB: "database1"
      POSTGRES_USER: "postgres"
    ports:
      - 5432:5432
  1. Install psycopg2-binary and Django
  2. django-admin.py startproject routing
  3. Edit routing/settings.py adding the following to the database
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'database1',
        'USER': 'postgres',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': '5432',
    },
    'database2': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'database2',
        'USER': 'postgres',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}
  1. Create database database2 in postgres
  2. Create a new app ./manage.py startapp integrations
  3. Add integrations app to INSTALLED_APPS in settings.py
  4. Create file router.py in integrations app
  5. Copy the following code into it. It is just a modification of what is in the Django docs.
APP_LABEL = "integrations"
DB_CONNECTION_NAME = "database2"


class IntegrationRouter:
    def db_for_read(self, model, **hints):
        if model._meta.app_label == APP_LABEL:
            return DB_CONNECTION_NAME
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == APP_LABEL:
            return DB_CONNECTION_NAME
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == APP_LABEL or obj2._meta.app_label == APP_LABEL:
           return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label == APP_LABEL:
            return db == DB_CONNECTION_NAME
        return None
  1. Add the following to settings.py for the database router to be used
DATABASE_ROUTER = ['integrations.router.IntegrationRouter']
  1. Run migration command ./manage.py migrate. It should run all migrations
  2. Run migration command ./manage.py migrate --database=database2. No migrations should be run, but on my system they are.
@tuantmtb
Copy link
Copy Markdown

Me too. How could I fix it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment