ChatGPT解决这个技术问题 Extra ChatGPT

How to simplify migrations in Django 1.7?

There are already similar questions for South, but I have started my project with Django 1.7 and am not using South.

During development a lot of migrations have been created, however the software is not yet delievered and there exists no database that must be migrated. Therefore I would like to reset the migrations as if my current model was the original one and recreate all databases.

What is the recommended way to do that?

EDIT: As of Django 1.8 there is a new command named squashmigrations which more or less solves the problem described here.

What does it mean to reset a migration? Undo it?

A
Aristide

I got this. I just figured this out and it is good.

First, to clear migrations table: ./manage.py migrate --fake zero

Remove app-name/migrations/ folder or contents.

Make the migrations: ./manage.py makemigrations

Finally tidy up your migrations without making other database changes: ./manage.py migrate --fake


This is a good answer. Just deleting the migrations doesn't undo any damage faulty migrations did. This actually cleans the slate and lets you start over.
If you'd elaborate a bit, this should be the accepted answer.
Great one line answer bro, I have no idea what this does
This line simply reverses migrations one by one, until zero. For Django migrations system, <app-name> is now a new app and makemigrations <app-name> will start from 0001. --fake prevents tables from actually getting modified, that migrations should only be marked reversed and not actually applied to schema. (Adding small explainations for the sake of completeness, @tani-rokk, @Fabrizio)
manage.py migrate --fake <app-name> zero to clear migrations table, then remove <app-name>/migrations/ folder or contents. Then manage.py makemigrations <app-name> and finally do manage.py migrate --fake <app-name>. This will tidy up your migrations without making other database changes.
t
tijs

In the Django 1.7 version of migrations the reset functionality that used to be in South has been dropped in favor of new functionality for 'squashing' your migrations. This is supposed to be a good way to keep the number of migrations in check.

https://docs.djangoproject.com/en/dev/topics/migrations/#squashing-migrations

If you still want to really start from scratch i assume you still could by emptying the migrations table and removing the migrations after which you would run makemigrations again.


How would I "remove the migrations" apart from emptying the migrations table? Would I remove the entire folder or just the 00X_*.py files?
with South you could remove the migrations folder which would be recreated when you run makemigrations again. I assume this works the same for Django 1.7
Just a note. in Django 1.7, if you, not carefully, delete the migration folder it may raise an exception if your model is a child of another raise KeyError("Migration %s dependencies reference nonexistent parent node %r" % (migration, parent))
Specifically ./manage.py squashmigrations myapp 0004 will squash all migrations before migration 0004 in your application myapp. This will create a single squashed migration.
s
shalbafzadeh

I just had the same problem. Here's my workaround.

#!/bin/sh
echo "Starting ..."

echo ">> Deleting old migrations"
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc"  -delete


# Optional
echo ">> Deleting database"
find . -name "db.sqlite3" -delete

echo ">> Running manage.py makemigrations"
python manage.py makemigrations

echo ">> Running manage.py migrate"
python manage.py migrate

echo ">> Done"

The find command: http://unixhelp.ed.ac.uk/CGI/man-cgi?find


this deletes the data, not just the migrations
you should delete .pyc files too
佚名

Assuming this is your project structure,

project_root/
    app1/
        migrations/
    app2/
        migrations/
    ...
    manage.py
    remove_migrations.py

you can run the script remove_migrations.py from the the place indicated above to delete all migrations files.

#remove_migrations.py
"""
Run this file from a Django =1.7 project root. 
Removes all migration files from all apps in a project.
""" 
from unipath import Path

this_file = Path(__file__).absolute()
current_dir = this_file.parent
dir_list = current_dir.listdir()

for paths in dir_list:
    migration_folder = paths.child('migrations')
    if migration_folder.exists():
        list_files = migration_folder.listdir()
        for files in list_files:
            split = files.components()
            if split[-1] != Path('__init__.py'):
                files.remove()

Manually deleting can be tiring if you have an elaborate project. This saved me a lot of time. Deleting migration files is safe. I have done this an umpteenth number of times without facing any problems...yet.

However when I deleted the migrations folder, makemigrations or migrate did not create the folder back for me. The script makes sure that the migration folder with its __init__.py stays put, only deleting the migration files.


you could just delete the migrations folders and recreate them with an empty init.py (e.g. touch migrations/__init__.py)
I
Ibrohim Ermatov

Delete files: delete_migrations.py (in root of prj):

import os for root, dirs, files in os.walk(".", topdown=False): for name in files: if '/migrations' in root and name != '__init__.py': os.remove(os.path.join(root, name))

DELETE FROM django_migrations Where app in ('app1', 'app2'); ./manage.py makemigrations ./manage.py migrate --fake

OR, you can write migration from this all


I had to specify the app names for ./manage.py makemigrations to work, like so: ./manage.py makemigrations orders alerts
c
chirale

I try different commands and some of the answers help me. Only this sequence in my case fixed both broken dependencies in migrations in MYAPP and clean all past migrations starting from scratch.

Before doing this ensure that database is already synced (e.g. do not add a new Model field here or change Meta options).

rm -Rf MYAPP/migrations/*
python manage.py makemigrations --empty MYAPP
python manage.py makemigrations
python manage.py migrate --fake MYAPP 0002

Where 0002 is the migration number returned by the last makemigrations command.

Now you can run makemigrations / migrate again normally because migration 0002 is stored but not reflected in the already-synced database.


Out of all solutions mentioned above, only this worked for me without a glitch and without deleting the database.
v
vokimon

If you don't care about previous migrations, what about just removing all migrations in the migrations/ directory? you will start the migration sequence from scratch, taking your current model as reference as if you had written the whole model now.

If you don't trust me enought to remove, then try to move them away instead.


What is the significance of keeping old migrations ? My questions hits ground when one tries to upgrade from django 1.6 to 1.8 .
Migrations are simply a track record of the changes you have made to the database. I've taken vokiman's advice more than once when my migration chain stops working.
s
sprksh

A simple way is

Go to every app and delete the migration files.

Then go to the django-migrtaions table in the database and truncate it(delete all entries).

After that you can create migrations once again.


while deleting migration files, make sure you do not delete the init files.
This really helped me. I deleted all migrations, dropped the tables from my sqlite DB, but was still unable to makemigrations...however, once I restored the _init_.py files (doh) I was able to makemigrations again and get cruising. @sprksh = Lifesaver!
v
vabada

cd to src directory cd /path/to/src

delete migration directories rm -rf your_app/migrations/

note that this should be done for each app separately

migrate python3.3 manage.py migrate

if you wish to start again python3.3 manage.py makemigrations your_app


m
mrmuggles

If you're in development mode and you just want to reset everything (database, migrations, etc), I use this script based on Abdelhamid Ba's answer. This will wipe the tables of the database (Postgres), delete all migration files, re-run the migrations and load my initial fixtures:

#!/usr/bin/env bash
echo "This will wipe out the database, delete migration files, make and apply migrations and load the intial fixtures."

while true; do
    read -p "Do you wish to continue?" yn
    case $yn in
        [Yy]* ) make install; break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no.";;
    esac
done

echo ">> Deleting old migrations"
find ../../src -path "*/migrations/*.py" -not -name "__init__.py" -delete

# Optional
echo ">> Deleting database"
psql -U db_user -d db_name -a -f ./reset-db.sql

echo ">> Running manage.py makemigrations and migrate"
./migrations.sh

echo ">> Loading initial fixtures"
./load_initial_fixtures.sh

echo ">> Done"

reset-db.sql file:

DO $$ DECLARE
    r RECORD;
BEGIN
    -- if the schema you operate on is not "current", you will want to
    -- replace current_schema() in query with 'schematodeletetablesfrom'
    -- *and* update the generate 'DROP...' accordingly.
    FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
        EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
    END LOOP;
END $$;

migration.sh file:

#!/usr/bin/env bash
cd ../../src
./manage.py makemigrations
./manage.py migrate

load_initial_fixtures.sh file:

#!/usr/bin/env bash
cd ../../src
./manage.py loaddata ~/path-to-fixture/fixture.json

Just be sure to change the paths to corresponds to your app. I personally have these scripts in a folder called project_root/script/local, and django's sources are in project_root/src.


s
shacker

After deleting each "migrations" folder in my app (manually), I ran:

./manage.py dbshell
delete from django_migrations;

Then I thought I could just do ./manage.py makemigrations to regenerate them all. However, no changes were detected. I then tried specifying one app at a time: ./manage.py makemigrations foo, ./manage.py makemigrations bar. However, this resulted in circular dependencies that could not be resolved.

Finally, I ran a single makemigrations command that specified ALL of my apps (in no particular order):

./manage.py makemigrations foo bar bike orange banana etc

This time, it worked - circular dependencies were automatically resolved (it created additional migrations files where necessary).

Then I was able to run ./manage.py migrate --fake and was back in business.


关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now