7

I'm building a website under Django Framework, this website needs to have different SQL schemes, for now I succeeded creating all schemes and all stuff, but I don't understand why the table django_migrations is in each schema after migration of databases.

  • Expected Databases Content:

    AppDB tables are all the models defined by this app

    Default DB tables are all Django tables (admin, contenttypes, auth, sessions)

  • Databases Content:

    AppDB tables are all the models defined by this app + django_migrations

    DEFAULT tables are all Django tables (admin, contenttypes, auth, sessions) + django_migrations

Those are the routers of the 2 dbs:

class DefaultRouter(object):
    APPS = ['auth', 'sessions', 'admin', 'contenttypes']
    DB = 'default'

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.APPS:
            return self.DB
        return None

    def db_for_write(self, model, **hints):

        if model._meta.app_label in self.APPS:
            return self.DB

        return None

    def allow_relation(self, obj1, obj2, **hints):

        if obj1._meta.app_label in self.APPS or obj2._meta.app_label in self.APPS:
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):

        if app_label in self.APPS:
            return db == self.DB
        return None


class MyAppDBRouter(object):
    def db_for_read(self, model, **hints):
        return self.check_app_label(model)

    def db_for_write(self, model, **hints):
        return self.check_app_label(model)

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

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label == 'myapp':
            return db == 'appdb'
        return None

    @staticmethod
    def check_app_label(model):
        if model._meta.app_label == 'myapp':
            return 'appdb'
        return None

Thanks.

  • You have written some comments replying to answers, and it appears the question as currently worded does not explain what it is you're asking. Can you edit the description to better explain the question you're asking? – bignose May 09 '18 at 23:18

3 Answers3

1

The django_migrations table records which migrations have been applied on that database. It's the mechanism by which the Django migration system understands the current state of the database and which migrations need to be run. So it's required on all the databases.

Now, if you had a table that didn't actually need migrations—say, a read-only database—then this could cause problems. That's the subject of this ticket.

Kevin Christopher Henry
  • 46,175
  • 7
  • 116
  • 102
  • I think that you didn't understand what I've asked for,my question is this, I have 2 db, one should include django informations, and the other one should include only data for my apps. when I migrate the project it creates the django_migrations table in both db with the same data, I tried almost everything to avoid this but nothing helped me – Nadir Albajari May 01 '16 at 10:35
  • @NadirAlbajari: It isn't possible. The other tables you mentioned are just optional apps, and can be put anywhere. The migrations table is not optional, it must exist on each database so it can track which migrations have been applied on that database. – Kevin Christopher Henry May 01 '16 at 11:02
  • Thanks @Kevin, I understand this, but assuming that I have 2 apps (app1, app2) and 2 databases (db1, db2), I would like to have the related migrations for app1 in db1 and the same for app2 in db2.but the migrations table in db1 contains the migrations for the 2 apps and the same for db2. is there a good reason why this happening?is there any way to have the migrations for 2 apps separated? Thanks again!! – Nadir Albajari May 02 '16 at 08:02
  • @NadirAlbajari: Django marks those migrations as applied, but it doesn't actually do anything when `allow_migrate()` returns `False`. That is what is meant by "silently" in this phrase from the [documentation](https://docs.djangoproject.com/en/1.9/topics/db/multi-db/#database-routers): "Note that migrations will just silently not perform any operations on a model for which this returns `False`." My opinion is that this is a poor design, and you can see a discussion of that in the ticket that I linked to. But what is the actual problem that this is causing you? – Kevin Christopher Henry May 02 '16 at 09:00
  • @KevinChristopherHenry I know this is old but 5 years later I've stumbled onto the same question about why `django_migrations` table contains all migrations for all dbs regardless of router settings that prevent the actual tables from getting migrated to an undesired db. I managed to prevent this by using, for example: `manage.py migrate polls --database=tutorial_db` where the `polls` option only attempts to run migrations on the polls app so django's default apps migrations don't appear in the `django_migrations` table of `tutorial_db`. I wonder if this is a good solution tho. Any thoughts? – Kevin Oct 28 '21 at 16:49
1

Prior to Version 1.7 of Django, there was no django_migrations table. Thereafter, Django rightly included migrations for handling database schema related changes, that is changes in field definition, addition or deletion of fields in db.models.

In Earlier versions, developers use django_south_migration app for doing exactly this but since almost everybody was using it, Django included in 1.7 version onwards.

Now coming to your question, django_migrations table keep records of changes in database schema applied to database. This table helps django in applying new migrations created after python manage.py makemigrations.

app column of this table records name of the app to which this migration was applied. If you will go to migrations directory of any django app, you will see migration files of the form 0001_auto.py etc.
eg if this migration has been applied to database, you will find an entry with name=0001_auto and app= in django_migrations table.

Amit Jaiswal
  • 985
  • 1
  • 9
  • 16
  • I think that you didn't understand what I've asked for,my question is this, I have 2 db, one should include django informations, and the other one should include only data for my apps. when I migrate the project it creates the django_migrations table in both db with the same data, I tried almost everything to avoid this but nothing helped me – Nadir Albajari May 01 '16 at 10:40
0

I had the same issues as you, when I ran python 'manage.py migrate --database=whatever', when I checked the dbshell, I could only see one table called django_migrations.... did a few tweacks that led me nowhere, then I change the name of my database into the router files and it worked!

for example if you called your database primary_db ... you should use in the routers the name that you registered in the settings file . see the example below ...

DATABASES = {
    'default': {},
    'primary': {
        'NAME': 'primary_db.sqlite3',
        'ENGINE': 'django.db.backends.sqlite3',        
    },
    'secondary': {
        'NAME': 'secondary_db.sqlite3',
        'ENGINE': 'django.db.backends.sqlite3',
    }
}

in your router file use primary as name and not primary_db ... that's the mistake I did ... hope this will help