openwisp / django-swappable-models

Swapper - The unofficial Django swappable models API. Maintained by the OpenWISP project.

Home Page:http://openwisp.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Failure with makemigrations

chrkr opened this issue · comments

I always get a failed field lookup during makemigrations if the base app ('reusableapp') already has a migration in place, and the derived app ('myapp') did not previously provide a swapped version of a swappable model, but now does provide one, and there is another (swappable?) model which has a foreign key to this newly added model. It does not matter whether the other model was original or swapped.

The error is a lookup failure for the swappable model in the init function of the StateApps class in Django (django/db/migrations/state.py). In that location the exception is ignored if the 'ignore_swappable' parameter is True but ONLY if also app_label == settings.AUTH_USER_MODEL.

Removing the limitation on app_label from Django seems to result in makemigrations completing successfully and correctly.

Running makemigrations only for 'myapp' does not matter.

Changing the reusableapp migration file as in the instructions does not make a difference. Django version also does not matter, anything from 1.7 up to 1.9 does this.

Swapping Child rather than Parent does not result in the same problems (note that there is no foreign key pointing to it).

Making additional changes to either model after successfully creating the initial ones does not pose any problems either (perhaps unless another foreign key is added but I haven't tested).

So it seems that using swapper with migrations already provided with the 'reusableapp' forces you to manually make an initial migration for the app/project which uses it. Unless I am missing something, in which case the README is incomplete.

Thanks for the report. In general, Django still has limited support for swapping a model after the initial migration - see Django ticket #25313 and the warnings in the AUTH_USER_MODEL documentation. That said, it does seem to sort of work - but then there are edge cases such this one, where AUTH_USER_MODEL is hardcoded in django/db/migrations/state.py (as you've noted). It would be better to establish a registry of all installed swappable models, and remove all explicit references to AUTH_USER_MODEL from django.db.migrations. I haven't yet found a Django ticket for fixing this, but presumably that is the long-term plan.

So, the short answer is that more work needs to be done in Django core for this to work. In the meantime, the most robust solution is to tell your users to start from the beginning with the swappable setting in place, or to be willing to wipe out their migrations (and potentially entire database) once they've established that they want to swap a model. I'll update the Swapper documentation to note this limitation.

I think this can be closed.