Hello, I am doing a refactor in my project and several models in various apps have a reference to a single function per app in the FileModel that needs to be replaced:
class MyModel:
file_path = models.FileField(upload_to=_upload_to, blank=True, null=True)
Now I want to replace in all models for all apps for this:
class MyModel:
file_path = models.FileField(upload_to=generic_upload_to, blank=True, null=True)
To reuse a single function for the uploads defined in a centralized projects/utils.py.
However there are references in several migrations for each app to the old _upload_to standing on the app directories and I cannot get rid of those (files aswell). That is the point of my refactor so, how can I bypass this to safely remove my many instances of _upload_to which are repeated per app?
Considerations:
This is a project in production, so migrations are tracked and database has data
I read about squashmigrations, the original _upload_to appears on the migration 00X for my apps, and I am on the 00Y (depends on the app but already ahead). Should I squash from X to Y? is that safe for production?
I know django migrations should not be edited manually but fixing the reference in the old migration file to the new generic_upload_to is possible or unsafe? As the migration is already applied so they should not be checked againâŚ
When looking to edit / squash / modify migrations, I believe itâs important to understand the context in which your project is being used.
In most cases, the advice is given under the expectation that there are âXâ number of different deployments of your system at âNâ different versions. Those recommendations are given to provide the most safety and security for all instances.
However, if youâre working with a more âcontrolledâ environment, where you know how many instances are being used, and that they are all up-to-date, and that you have no responsibility to run or maintain a previous version, then you have a lot more flexibility. It may not be important, or even necessary, to be able to migrate to/from some intermediate step over time.
Most of the systems that I have worked on were internal systems like that. In those cases, we didnât worry about migrations history. It was common for us to ârebaseâ the models by deleting all existing migration files and empyting the migration history table, creating the âinitialâ migration from the current state of the project, and then adding back in any manually created migration steps that may still be necessary.
Thanks for the context @KenWhitesell. We are definitely not in need to migrate to old stages. So migration history is definitely not used.
Then, I can emtpy the migration history table and files to generate a new one? If so, the existing data will match the current schema? or will be problems pairing the âexistingâ data with the new migration file?
If your current models match the existing schema, then the initial migration will create a migration for the models as they currently exist. If those models match the database schema, then you can run migrate --fake to have Django record those migrations as having been applied - but nothing is actually changed.
You would then run makemigrations after making changes, and those updates would then be applied to your schema.
py manage.py showmigrations # look the all of the migration list
py manage.py makemigrations <app_name> --empty # the empty migration & flag '--skip-checks ' s But with '--skip-checks' you be careful.
py manage.py migrate <app_name> zero # cancel the all migrations before the zero (index) migration
py manage.py migrate <app_name> <name_migration> # cancel before the <name_migration> migration/