20

How do I completely reset my Django (1.2 alpha) DB (dropping all tables, rather than just clearing them)?

manage.py flush does too little (won't work if there are schema changes) and manage.py reset requires me to specify all apps (and appears to take a format that is different from just " ".join(INSTALLED_APPS)). I can obviously achieve this in a DB specific way, but I figured there must be a sane, DB backend agnostic way to do this.

[Edit: I'm looking for something that I can call from a script, e.g. a Makefile and that continues to work if I change the backend DB or add to settings.INSTALLED_APPS]

7 Answers 7

21

This Snippet gives you the code for a manage.py reset_db command you can install, it's the minimum change that solves your problem


That said, from comments below:

You might as well just install Django command extensions to get reset_db and other goodies: https://github.com/django-extensions/django-extensions

Sign up to request clarification or add additional context in comments.

5 Comments

You might as well just install Django command extensions to get reset_db and other goodies: code.google.com/p/django-command-extensions
it's just: pip install django-extensions and then python manage.py reset_db
To complete @abstraktor comment: before typing python manage.py reset_dbyou need to enable django_extensions in your project you need to add it to INSTALLED_APPS in your projects settings.py file: INSTALLED_APPS = ( ... 'django_extensions', ... ) see the doc
Django commands extensions is perhaps the most ideal way to do this.
This is the golden answer. It's just simple and sweet.
1

You want sqlreset:

% python manage.py help sqlreset
Usage: manage.py sqlreset [options] <appname appname ...>

Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given app name(s).

Options:
  -v VERBOSITY, --verbosity=VERBOSITY
                        Verbosity level; 0=minimal output, 1=normal output,
                        2=all output
  --settings=SETTINGS   The Python path to a settings module, e.g.
                        "myproject.settings.main". If this isn't provided, the
                        DJANGO_SETTINGS_MODULE environment variable will be
                        used.
  --pythonpath=PYTHONPATH
                        A directory to add to the Python path, e.g.
                        "/home/djangoprojects/myproject".
  --traceback           Print traceback on exception
  --version             show program's version number and exit
  -h, --help            show this help message and exit

Just like when you modify a model, Django will not automatically do this for you. It will only output the commands for you to copy and paste.

2 Comments

manage.py reset which I mentioned above just is a wrapper around sqlreset so exactly the same problem applies: I don't want to manually list all the appnames. I want a solution that can be automated and continues to work if I add to INSTALLED_APPS in settings.py.
You're gonna have to roll your own script then. I don't think this functionality exists as-is.
0

Just assign a new database and drop this db from the db console. Seems to me to be the simplest.

2 Comments

Sorry, I should have made it clear that I need something that can be automated.
@as: How is a database drop not automatable? What's your database? Write a SQL script to DROP DATABASE x; and run it.
0

Hm, maybe you lie to manage.py, pretending to make fixtures, but only to look for apps:

apps=$(python manage.py makefixture 2>&1 | egrep -v '(^Error|^django)'|awk -F . '{print $2}'|uniq); for i in $apps; do python manage.py sqlreset $i; done| grep DROP

That prints out a list of DROP TABLE statements for all apps tables of your project, excluding django tables itself. If you want to include them, remove the |^django pattern vom egrep.

But how to feed the correct database backend? sed/awk-ing through settings.conf? Or better by utilizing a little settings.conf-reading python script itself.

Comments

0

Assuming you are (luckily) in a Linux environment as well as:

  • using MySQL and know user/password to access project's db
  • bash, mysql, readlink are installed
  • settings.py is settings.py
  • dbname is the same as your django project name (see MYAPP var below)
  • all the APPS you want to reset are listed in INSTALLED_APPS as strings with fully qualified module names (starting with the name of your django project)

Change your current folder to your project code where manage.py and settings.py reside. Then run the following:

MYAPP=$(basename $(dirname `readlink -m settings.py`));DJANGOAPPS=$(echo 'import settings; print " ".join([ str(app).lstrip("'${MYAPP}'.") for app in settings.INSTALLED_APPS if "'${MYAPP}'" in app ])' | python - ); python manage.py sqlreset $DJANGOAPPS | mysql -u root --password ${MYAPP}

If you understand what is going in this bash oneliner - it should not be a problem to build upon this idea (e.g. put it to Makefile).

1 Comment

Note that echo 'DROP DATABASE dbx;' | mysql dbx as suggested by S.Lott also works in the world of unix command line. Then you just call syncdb
0

In Django 3.1.1

if you want to totally reset the database and the schema then put this code in any app like this

app/management/commands/resetdb.py

import os
import glob
import shutil
from django.conf import settings
from django.core.management.base import BaseCommand
from django.db import connection


class Command(BaseCommand):
    help = 'Resets the database'

    def handle(self, *args, **options):
        dbname = settings.DATABASES["default"]["NAME"]
        with connection.cursor() as cursor:
            cursor.execute("DROP DATABASE %s" % dbname)
            cursor.execute("CREATE DATABASE %s" % dbname)

        base = str(settings.BASE_DIR)
        migrations = glob.glob(os.path.join(base, "*", "migrations"))

        for migration in migrations:
            shutil.rmtree(migration)

        apps = [migration.split("\\")[-2] for migration in migrations]
        for app in apps:
            os.system("python manage.py makemigrations %s" % app)
        os.system("python manage.py migrate")

now reset it using :

python manage.py resetdb

this will

  • drop the database
  • delete the migrations folders
  • make migrations
  • create a new db
  • migrate the fresh tables

Comments

-2

take a look at reset command in django's code, and write your own which drops/creates DB first.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.