Opened 10 years ago

Closed 10 years ago

#23135 closed Bug (needsinfo)

Multiple routers cause problems with migration/sql management commands

Reported by: Geladriet Owned by: nobody
Component: Core (Management commands) Version: 1.7-rc-2
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Hello

I'm currently testing django 1.7 as much as I can with our multiple database configuration and found an bug.

If you are using multiple routers, there seems a problem to get the right target database.

Sample:

settings.py
DATABASE_ROUTERS = ['SampleModel.router.SampleModelRouter', 'SampleModel2.router.SampleModelRouter2']

Both models and routers are the same but have another name.

router.py

class SampleModelRouter2(object):
    """
    A router to control all database operations on models.
    """

    def db_for_read(self, model, **hints):
        """
        Attempts to read go to game db.
        """
        if model._meta.app_label == 'SampleModel2':
            return 'second_db'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write go to game db.
        """
        if model._meta.app_label == 'SampleModel2':
            return 'second_db'
        return None

    def allow_migrate(self, db, model):
        """
        Make sure the app only appears on the right db.
        """
        if db == 'second_db':
            return model._meta.app_label == 'SampleModel2'
        elif model._meta.app_label == 'SampleModel2':
            return False
        return None

Output model 1 sqlall:

[mgysin@localhost Demo]$ python manage.py sqlall SampleModel --database=second_db
BEGIN;
CREATE TABLE "SampleModel_location" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    "name" varchar(50) NOT NULL
)
;

COMMIT;

Now the same for model 2:

[mgysin@localhost Demo]$ python manage.py sqlall SampleModel2 --database=second_db
[mgysin@localhost Demo]$ 

If I change the order of the routers, model 2 starts working:

settings.py
DATABASE_ROUTERS = ['SampleModel2.router.SampleModelRouter2', 'SampleModel.router.SampleModelRouter']

sqlall:

[mgysin@localhost Demo]$ python manage.py sqlall SampleModel2 --database=second_db
BEGIN;
CREATE TABLE "SampleModel2_location" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    "name" varchar(50) NOT NULL
)
;

COMMIT;

Attached is the sample project with the problem.
Please note this bug is also in 1.7-rc-1

Greets
Manuel

Attachments (1)

SampleApp_routers.tar.gz (2.9 KB ) - added by Geladriet 10 years ago.
Sample project

Download all attachments as: .zip

Change History (4)

by Geladriet, 10 years ago

Attachment: SampleApp_routers.tar.gz added

Sample project

comment:1 by Geladriet, 10 years ago

A workaround for the problem:

    def allow_migrate(self, db, model):
        """
        Make sure the app only appears on the right db.
        """
        if db == 'second_db':
            if model._meta.app_label in ('SampleModel2', 'SampleModel'):
                return True
            else:
                return False
        elif model._meta.app_label in ('SampleModel2', 'SampleModel'):
            return False
        return None

If I think more about it, the current behavior is more or less right. But works completely different then in Django 1.6.
This can leads to confusion because of the current sample in the documentation.

comment:2 by Tim Graham, 10 years ago

Is this addressed by the documentation added in #23102? If not, could you suggest edits or additional text?

comment:3 by Tim Graham, 10 years ago

Resolution: needsinfo
Status: newclosed
Note: See TracTickets for help on using tickets.
Back to Top