user1283776
user1283776

Reputation: 21824

Simple way to reset Django PostgreSQL database?

I was able to reset a Django PostgreSQL database using the following steps:

  1. Delete migration files
  2. Enter psql command prompt. Connect to database. drop schema public cascade; create schema public;
  3. Step 2 unfortunately seemed to have removed my user role and rights so I went back to the psql command promt and recreated those.
  4. Step 2 also meant I needed to run the following commands in the psql command prompt: grant usage on schema public to public; grant create on schema public to public;
  5. Step 2 also deleted the standard Django users I had created so I needed to recreate these
  6. python manage.py makemigrations && python manage.py migrate

I am currently making changes to my models and testing each change. I don't have any data I need to keep. Is there an easier way than the above to reset the database when migrations donät work?

I would at least like to replace step 2 with something else so that I can skip steps 3-5.

Upvotes: 33

Views: 54356

Answers (8)

sgaudreau
sgaudreau

Reputation: 1

A simple command called reset_db() exists for this in the django-extensions package.

https://django-extensions.readthedocs.io/en/latest/reset_db.html

It uses the current database configured in your project's settings by default, but can be changed to whatever your needs are RE: the documentation.

(Bonus is that you also get a number of other useful development utilities with this package, like the mega time saving Django shell_plus)

Upvotes: 0

Jura Brazdil
Jura Brazdil

Reputation: 1100

If you want a completely clean start, you're gonna wanna stick to dropping the DB. Which means the steps you mention - recreate it, add privileges, re-generate all the migrations and re-run them.

Good news is that you can easily make all this into a single/few line commands.

Fresh migration files

If you delete the whole folders, you're gonna have to run the makemigrations command mentioning all the app names. That's a hassle if you do this often. To have Django see the apps that need migrations, you'll wanna keep the migrations folder and the __init__.py inside them.

Here's a bash command for that:

find . -path "*migrations*" -not -regex ".*__init__.py" -a -not -regex ".*migrations" | xargs rm -rf

Then the usual (this should create migrations for all the apps that had migrations before):

python manage.py makemigrations

Resetting the PostgreSQL DB

Run this in the console:

psql -c "drop database <db_name>;"
psql -c "create database <db_name>;"
psql -c "grant all on database <db_name> to <db_user>;"

And then finally re-run migrations with

python manage.py migrate

Superuser

You're gonna obviously be missing a superuser, so you might wanna also do:

python manage.py createsuperuser

No-input way of doing that is piping python code into the shell:

echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', '[email protected]', 'pa$$w0rd')" | python manage.py shell

Generally speaking about these very common actions - Do yourself a favour and write a bit of bash. It has saved me many, many accumulated hours over the years of working with not only Django. Because even better than a oneline command is having a whole utility file to store more of these handy functions. Then you can just run something like:

django --reset_migrations
db --reset <my_db>
django --migrate

Or even aggregate that into a single line if you find yourself repeating the same few actions.

reset_django() {
    find . -path "*migrations*" -not -regex ".*__init__.py" -a -not -regex ".*migrations" | xargs rm -rf
    python manage.py makemigrations
    psql -c "drop database <db_name>;"
    psql -c "create database <db_name>;"
    psql -c "grant all on database <db_name> to <db_user>;"
    python manage.py migrate
    echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', '[email protected]', 'pa$$w0rd')" | python manage.py shell
}

My utilities for inspiration

#!/bin/bash


django() {

    project_name=$(basename $PWD)
    project_path="$PWD"
    manage_path="${project_path}/${project_name}/manage.py"

    if [ ! -f $manage_path ] ; then  # No project/manage.py
        echo "Error: Could not locate Django manage.py file."
        return -1
    fi

    if [ $# -eq 0 ] ; then
        echo "Django project detected."
    fi

    while [ ! $# -eq 0 ]
        do
            case "$1" in

                --help | -h)
                        echo "Django shortcut, unknown commands are forwarded to manage.py"
                        echo "  -c, --check         Run Django manage.py check."
                        echo "  --req           Install requirements."
                        echo "  -r, --run           Run server."
                        echo "  -s, --shell         Run Django shell plus."
                        echo "  -sd, --shell            Run Django shell plus. Debug DB (print sql)"
                        echo ""
                    ;;

                --check | -c)
                        python $manage_path check
                    ;;

                --shell | -s)
                        python $manage_path shell_plus --bpython
                    ;;

                --shell | -sd)
                        python $manage_path shell_plus --bpython --print-sql
                    ;;

                --run | -r)
                        python $manage_path runserver
                    ;;

                --req)
                        pip install -r $project_path/requirements.txt
                    ;;

                --mig | -m)
                        python $manage_path makemigrations
                        python $manage_path migrate
                    ;;

                --reset_migrations)
                        find . -path "*migrations*" -not -regex ".*__init__.py" -a -not -regex ".*migrations" | xargs rm -rf
                        python $manage_path makemigrations
                        ;;

                *)
                    python $manage_path "$@"
                    ;;

            esac
            shift
        done

}

Upvotes: 2

Franck CHARLES
Franck CHARLES

Reputation: 201

With Python

from django.db import connection

with connection.cursor() as cursor:
    cursor.execute("DROP SCHEMA public CASCADE;")
    cursor.execute("CREATE SCHEMA public;")

then,

python manage.py migrate

Upvotes: 10

Ritesh Mukhopadhyay
Ritesh Mukhopadhyay

Reputation: 73

first you need to remove the migration file from your project. And then run the psql database using terminal window(make sure anything related to the database and projects should be closed so, that no instance of the db should be running). Then follow the following link to remove the db from the terminal window https://www.postgresqltutorial.com/postgresql-drop-database/

hope this answers the problem. I myself ran into the same problem and this steps fixed it. Happy developing!

Upvotes: -2

Xandrix
Xandrix

Reputation: 504

I successfully "reset my django postgreSQL database" (while not losing data).

Updating my models.py and then using ./manage.py makemigrations and ./manage.py migrate wasn't possible because the table(s) I needed to rename pointed to one another circularly. Django was not unable to "auto-magically" accomplish said task.

So, I opted to backup my data. Flush. Delete the tables. Update my models.py file. Modify the (json) backup I created (using ./manage.py datadump > fileName.json) to reflect my updated column names/table names. Then, I recreated the database using ./manage.py migrate and ./manage.py makemigrations. Then I loaded my backup back into the database's newly created tables using ./manage.py loaddata fileName.json.

The exact steps I took:

  1. First I took a backup of my server/VM.
  2. ./manage.py dumpdata > db.json
  3. ./manage.py flush
  4. Choose "Yes" [NOTE THIS DELETES ALL YOUR DATA!!!]
  5. Delete all tables from --myDataBaseName--
  6. Delete your migrations folder
  7. Make your changes (if you have any) to your model.py file
  8. ./manage.py migrate
  9. ./manage.py makemigrations --myAppName--
  10. ./manage.py migrate --myAppName--
  11. go into db.json and remove contenttype related stuffz. You may also need to remove (and seed manually after step 12 in some cases) auth_permissions related entries in your db.json. Save modified db.json as db_new.json so that you don't lose your original backup in case things get fubar'd and you need to put everything back to how it was!
  12. ./manage.py loaddata db_new.json

Upvotes: 9

Th&#233;o T. Carranza
Th&#233;o T. Carranza

Reputation: 8459

If you are using docker/composer, issue an docker-compose down and then migrate.

Upvotes: 8

Daniel Roseman
Daniel Roseman

Reputation: 600059

I don't understand why you think you need to delete either migrations or the database. The whole point of migrations is that they build on what has gone before; you should never need to delete and start again. Just do makemigrations every time you make a change, and the series of migrations should always work.

Later, you may want to squash a set of migrations into one, for the sake of speed, which is again supported natively. But never delete the migrations you have already run.

Upvotes: 1

Ihor Pomaranskyy
Ihor Pomaranskyy

Reputation: 5651

Probably the easiest way to do this is to recreate the whole database. In Ubuntu, it looks like this:

sudo su postgres
psql
drop database your_database_name;
create database your_database_name with owner user_you_use_in_django;
\q
exit

That's it. You have clean database. To make it ready to go, you have to run migrations with python manage.py migrate.

If you are working on your project alone, you can delete and recreate migrations, if you want.

Upvotes: 51

Related Questions