简体   繁体   中英

Why is django_migrations table in all databases

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.

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 .

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 app for doing exactly this but since almost everybody was using it, Django included in 1.7 version onwards.应用程序来完成此操作,但由于几乎每个人都在使用它,因此 Django 包含在 1.7 版本中。

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM