11

Is there a way to exclude models of an app from Django migrations? I know changing the model meta options with managed = False is an option but that's a lot of models to edit every time. Is there a way to specify an app whose models I don't want to migrate?

cookiedough
  • 3,552
  • 2
  • 26
  • 51

3 Answers3

8

remove the app from installed apps in your settings.

Ian Kirkpatrick
  • 1,861
  • 14
  • 33
  • 3
    and you have to add `app_label = 'the_app'` in `class Meta` of each model of the app – epineda Jul 31 '19 at 03:43
  • @epineda Thanks for the comment, this worked for me. The approved answer recreated the `__init__.py file everytime for me. – Alfa Bravo Aug 09 '19 at 09:11
  • @AlfaBravo Are you using an IDE? or just a slim text editor? That's probably your IDE adding them back if you are running the command through the IDE. – Ian Kirkpatrick Aug 26 '19 at 12:18
  • @IanKirkpatrick I am using vs-code, but thanks for the heads up. When I have this problem again I would try and see if there is a difference in the two use cases. – Alfa Bravo Aug 26 '19 at 12:33
8

Removing the __init__.py file from within the apps migrations directory should work.

audeos
  • 336
  • 2
  • 6
  • 3
    This answer is the right answer to specifically the question I asked. In my case however, I am using dynamic models. When I generate them at runtime, I run `makemigrations` and `migrate` to add them to the models of the app. So this in my case will not work. Do you have any ideas for working with dynamic models? – cookiedough Jul 25 '17 at 21:07
  • 1
    Hmm, not sure about dynamic models, but maybe you could "touch" the `__init__.py` file at runtime, using `os` or `pathlib` libraries, after making the models? [link](https://stackoverflow.com/questions/1158076/implement-touch-using-python) – audeos Jul 25 '17 at 22:37
  • 2
    This is a hack way of doing this. Yes it works, but that's because it makes the migrations directory not a package. The migration files are no longer importable... that's why they don't work... they aren't even considered code. The proper way to do this is to tell Django not to include them... not to effectively wipe them from existance. – Ian Kirkpatrick Aug 26 '19 at 12:15
  • Although I suppose if you only want to exclude it 1 time and then continue including it always, this is a fine way of doing this as long as you add the __init__.py back right away so that Django can see the files again. – Ian Kirkpatrick Aug 26 '19 at 12:16
0

You can do this if you use database routers with

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

Example.

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

    def db_for_write(self, model, **hints):
        """
        Attempts to write filemaker models go to filemaker.
        """
        if model._meta.app_label == 'filemaker':
            return 'filemaker'
        return None

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

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

Search duckduckgo for more details

Keith John Hutchison
  • 4,955
  • 11
  • 46
  • 64