Deleted Migration folder (Django 1.8) by accident what are my options? - django

I have accidently deleted one of migrations folders and and have no backup for it.
What are my options?
DB is postgres. Right now everything is OK.(I have moved instead migration folder I have on my DEV server with SQL lite) So I am just getting red message on server that not all migrations have been applied.
But next time if i run migration i will be in trouble.
What is my way out?

Migrations are mainly for backward compatibility, and tracking/versioning of the changes to models/database. If you do not really care about historical changes, etc.. then you can just delete the migrations directory and do:
python manage.py makemigrations <app_name>
This creates the initial migrations (like starting from a clean slate) - and moving forward you can track the historical migrations moving forward. More on this can be read here
Now, when you run the migrations, you can do
python manage.py migrate <app_name> --fake-initial
to fake the initial migration.
Now might be a good time to have a version control on your application

Use version control.
You are not the first developer to delete important files, but often recovery takes less than a second - thanks to version control systems (also called revision control systems). Please stop everything else and install and use one of Git, Mercury or Subversion.
Don't use FTP
It's totally. I mean totally insecure. Always use SFTP
Don't use sqlite3 for local with other db for production
sqlite doesn't enforce strict type checking. Postgresql on the other hand is very particular about it. Additionally sqlite only has a subset of the functionality that's found on postgresql. Last but not least different RDBMS have different intricacies. If you use one locally and another in production, there is always a chance that your code will break when you deploy to live
Managing without the migration files
This is not a big loss as long as your database is in sync with your models.
If you database is not in sync with your models, you can use
./manage.py inspectdb
to recreate local models that represent the actual structure in the db. Then you do makemigrations and migrate (as explained by karthik) on the generated models.
Then replace that with your live models and do the step again.

Related

Django REST committing migration files to production

I have a django REST project and a PostgreSQL database deployed to DigitalOcean. When I develop locally, I have a separate dockerized REST server and a separate PostgreSQL database to test backend features without touching production data.
My question arises when I'm adding/modifying model fields that require me to make migrations using python [manage.py](https://manage.py) makemigrations and python [manage.py](https://manage.py) migrate command. Here is my current situation so far:
What I was supposed to do
IN LOCAL ENV, to create the migration files,
python manage.py makemigrations
python manage.py migrate
Now commit these newly created files, something like below.
git add app/migrations/...
git commit -m 'add migration files' app/migrations/...
IN PRODUCTION ENV, run only the below command.
python manage.py migrate
What I did so far
IN LOCAL ENV, created the migration files,
python manage.py makemigrations
python manage.py migrate
I committed & pushed the changes to production WITHOUT the created migration file
IN PRODUCTION ENV, ran BOTH commands.
python manage.py makemigrations
python manage.py migrate
The production server successfully added the isActive field to the database and is working fine, but I still have a 0011_user_isActive.py migration file in my local changes that hasn't been staged/committed/pushed to github repo.
And because I ran makemigrations command in production env, it probably created the same migration file that I haven't pushed from local env.
My questions are:
What happens if I push the local migration file to production? Wouldn't it create a conflict when I run migration command on digitalocean console in the future?
How should I fix this situation?
I am just scared I'm going to corrupt/conflict my production database as I'm very inexperienced in databases and have too much to risk at the moment. Would appreciate any tips on best practices when dealing with such situations!
As docs says:
The migration files for each app live in a “migrations” directory inside of that app, and are designed to be committed to, and distributed as part of, its codebase. You should be making them once on your development machine and then running the same migrations on your colleagues’ machines, your staging machines, and eventually your production machines.
So it's best practice is to push your migration files and make your local and production migration files sync.
And if you got conflict when pushing migraions files and pulling them, the makemigrations --merge command is for solving that.
Also docs says:
Because migrations are stored in version control, you’ll occasionally come across situations where you and another developer have both committed a migration to the same app at the same time, resulting in two migrations with the same number.
Don’t worry - the numbers are just there for developers’ reference, Django just cares that each migration has a different name. Migrations specify which other migrations they depend on - including earlier migrations in the same app - in the file, so it’s possible to detect when there’s two new migrations for the same app that aren’t ordered.
When this happens, Django will prompt you and give you some options. If it thinks it’s safe enough, it will offer to automatically linearize the two migrations for you. If not, you’ll have to go in and modify the migrations yourself - don’t worry, this isn’t difficult, and is explained more in Migration files below.
Also be aware that in case of updating existed data in production, you can use RunPython in migration file. Read about it here.

Django: Safely Remove Old Migrations?

I've got a Django app with a lot of out-of-date migrations. I'd like to remove the old migrations and start fresh.
The app has 14 different "migrations" folders.
Here is what a few of them look like:
Is it safe to remove all the contents from each of these folders? Or, do I have to make sure to only remove some of the files -- and if so which files?
You should never just delete migrations before unapplying them, or it will be a nightmare when you want to apply new migrations.
To unapply migrations you should do the following:
Use the python manage.py migrate your_app_name XXXX in case you want to unapply migrations after the XXXX migration. Otherwise use python manage.py migrate your_app_name zero to completely unapply all migrations.
Remove the .pyc files under /migrations/_pycache_/ that you have unapplied.
Remove the .py files under migrations/ that you have unapplied.
Now you can create new migrations without any headaches.
If what you're looking for is to squash all the migrations into one, do the steps above removing all migrations and then run python manage.py makemigrations your_app_name to create a single migration file. After that just run python manage.py migrate your_app_name and you're done.
That depends. If you have a production database (or any database you cannot simply drop and recreate), then the answer is no, you cannot safely remove migrations.
If you do not have any permanent databases, then yes, you can remove all migrations, run python manage.py makemigrations --initial and it will create fresh migrations based on your current models.
Also, you should check if any of the migrations are custom data migrations written by hand. If there are any, you might want to keep those.
The .pyc files are generally safe to remove, provided the related .py files are still there.
your first screenshot is not Django and looks like a JS project of some sort.
The json and js files are unrelated to the django migrations as well as __pycache__ folder. You can delete all off them.
If you mean "previously applied and no longer needed as the project only needs the latest version of the migrations" you don't want to remove but squash them instead with squashmigrations which reduces the files you have to two, init file and the initial migration file, this way your project still works.
If by remove you mean you no longer need them because you already changed the models so much that the previous migrations aren't even used other than being applied and unapplied without ever being used, doesn't matter, go to step 2 and do that instead of deleting the files manually. When you create migrations on your applications one by one, you also create migration dependency tree, well, django does. And it is really hard to keep track of after some point, if you try to delete everything thinking you can create new migration files with ease, trust me as someone who experienced otherwise, it does not work like that. It is way simpler to let django handle the migration squashing, it optimizes the migration meaning that it also deletes the unused ones in your final state.
More to read at: https://docs.djangoproject.com/en/2.2/topics/migrations/#migration-squashing
Having marked one of the answers provided previously as being accepted, here is a summary of a few things I learned:
Deleting Django migrations is generally a bad idea.
Django keeps track of what's in your db through these migration files, as well as through a table it creates in your db, and if you delete any of this Django will start throwing errors on migrate that can be hard to fix.
I was getting some of those hard-to-fix errors. Here is what I did to fix it:
Ran migrate on the production server.
When I got an error, it would tell me how the db was out of sync with what Django expected. I corrected that manually by directly editing the db with an sql client.
E.g. If it said a key existed that wasn't supposed to exist, I deleted the relevant index from the indicated table.
Or if it said a table existed that wasn't supposed to exist, I backed up the table to a file, and deleted the table. Migrate then created the table, and then I repopulated it with data from the backup.
In the case of many-to-many tables, once Django had re-created them, I deleted all the new Django-created tables, and restored them from a backup created on my local dev system, which had already had all the latest migrations run on it.
Eventually I was able to complete all migrations successfully.
I have a feeling I lucked out and the above won't work in all cases! I've learned a lot about Django and migrations and will be much more careful about this in the future.
when you import from third app:
there are 2 step uninstall it
there are use the 'django_celery_beat' app for example.
step1: clean table
python .\manage.py migrate django_celery_beat zero
step2: remove app from INSTALLED_APPS
there are done!!!
this is django document on this.
How to Reset Migrations
if you are using linux/unix os then you can fire this command. delete all migration directory.
find . -path "/migrations/.py" -not -name "init.py" -delete
find . -path "/migrations/.pyc" -delete

Django migrations gives error when run separately in different machines

We are a team of developers working on Django project. We are facing issues with django migrations. if one developer makes changes in model and runs makemigrations>migrate sequence it generates some sqls in migrations directory. Now when other developer pulls the code, and run the same sequence it's putting code in bad state. We've been clearing our migrations directory locally to get rid of the issue, and sometimes clear all the data. Not sure what we're doing incorrectly. Please suggest the right way of using django migrations.
Note - All of us use separate instances of DB in local machine.
makemigrations just create files
By running makemigrations, you’re telling Django that you’ve made some changes to your models (in this case, you’ve made new ones) and that you’d like the changes to be stored as a migration.
Migrations are how Django stores changes to your models (and thus your database schema) - they’re just files on disk. You can read the migration for your new model if you like; it’s the file polls/migrations/0001_initial.py.
Under Version Control, after you push the migrations file, for example, 0001_initial.py. Other developers just pull the file then run
python manage.py sqlmigrate your_app 0001 # to see what happen
python manage.py migrate your_app 0001
More about the Version Control:
Version control
Because migrations are stored in version control, you’ll occasionally come across situations where you and another developer have both committed a migration to the same app at the same time, resulting in two migrations with the same number.
Don’t worry - the numbers are just there for developers’ reference, Django just cares that each migration has a different name. Migrations specify which other migrations they depend on - including earlier migrations in the same app - in the file, so it’s possible to detect when there’s two new migrations for the same app that aren’t ordered.
When this happens, Django will prompt you and give you some options. If it thinks it’s safe enough, it will offer to automatically linearize the two migrations for you. If not, you’ll have to go in and modify the migrations yourself - don’t worry, this isn’t difficult, and is explained more in Migration files below.

How to merge consecutive database migrations in django 1.9+?

Migrations allow transforming from one database schema to another while maintaining current data in the database. Django allows creating migrations using the command python manage.py makemigrations
Each time makemigrations is run a new migration file 000n.. is added based on the changes detected in the models.py file.
Sometimes after making small changes to models.py, I want to run makemigrations but do not want a new migration to be created because the previous migrations haven't been used yet which allows them to be merged together, primarily because running each migration in production can take a lot of time when there is a lot of data in the database so merging migrations before hand may be preferable.
Is there a way to allow a new migration 000n.. to be merged with an existing migration 000(n-1).. ?
The command you are looking for is squashmigrations. It will merge all the unapplied migrations of a given app into a single file.
I want to run makemigrations but do not want a new migration to be
created because the previous migrations haven't been used yet
This is not a problem, Django runs migrations from top to bottom, meaning: your latest migration file will wait until other previous migration files are ran.
because running each migration in production can take a lot of time
when there is a lot of data in the database
How much data do you have in the database? If really much, then you must already have replications and redundant db servers. In this case, switch the reads and writes to one, say slave server, run the migrations in the master. and then switch the traffic back to master, and before that make sure that the lag between them is 0 and new schema is replicated properly among them

What is the correct way to deal with DB migration while using South, Django and Git?

Background :-
I am using Django 1.3. We are using South as the module for DB migration and Git SCM.
Problem:-
What is the correct way to deal with the migrations Folder that is formed?
The main problem is I make changes in the DB schema in the development machine, when I upload it to the production server I have to migrate the existing schema. While doing that there is always some issue with the migration files.
Should I just add the migrations folder to the gitignore ? or is there a better way to go about it ?
You should add the migrations folder to your version control system and use the same files for production and development. You may run into some problems on your production system if you introduced your migrations not from the beginning and you have already existing tables.
Therefore you have to fake the first migration, which normally does the same thing as syncdb did when you created your database for the first time.
So when trying to apply migrations for your app for the first time on the production machine, execute manage.py migrate app_name 0001 --fake. This lets South know, that the first migration has already been applied (which already happend with syncdb) and when you run migrate again, it would continue with the following migrations.