Reputation: 21824
I was able to reset a Django PostgreSQL database using the following steps:
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
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
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
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
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
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:
Upvotes: 9
Reputation: 8459
If you are using docker/composer, issue an docker-compose down
and then migrate
.
Upvotes: 8
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
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