¿Cómo eliminar todas las tablas de la base de datos con manage.py CLI en Django?


92

¿Cómo puedo eliminar todas las tablas de una base de datos usando manage.py y la línea de comandos? ¿Hay alguna forma de hacerlo ejecutando manage.py con los parámetros adecuados para poder ejecutarlo desde una aplicación .NET?

Respuestas:


127

Hasta donde yo sé, no hay un comando de administración para eliminar todas las tablas. Si no le importa hackear Python, puede escribir su propio comando personalizado para hacerlo. Puede encontrar la sqlclearopción interesante. La documentación dice que ./manage.py sqlclear imprime las instrucciones SQL DROP TABLE para los nombres de aplicaciones dados.

Actualización : Apropiando descaradamente el comentario de @Mike DeSimone debajo de esta respuesta para dar una respuesta completa.

./manage.py sqlclear | ./manage.py dbshell

A partir de django 1.9 es ahora ./manage.py sqlflush


sqlclear "imprime las declaraciones de caída" pero cómo ejecutarlas en una sola llamada de línea de comando
kmalmur

3
necesita el nombre de la aplicación como:./manage.py sqlclear myAppName | ./manage.py dbshell
Montaro

4
Esto no funciona en absoluto. sqlclear necesita un nombre de aplicación. Estoy en Django 1.8
Jonathan Hartley

1
Solo tenga en cuenta que sqlflush no elimina las tablas, las trunca. Además, esta operación probablemente no funcionará en su base de datos postgresql a menos que agregue la palabra clave CASCADE al final del comando truncar generado por sqlflush.
user3748764

35

No hay un comando de administración nativo de Django para eliminar todas las tablas. Ambos sqlcleary resetrequieren un nombre de aplicación.

Sin embargo, puede instalar Django Extensions, que le brinda manage.py reset_db, que hace exactamente lo que desea (y le brinda acceso a muchos más comandos de administración útiles).


@JulienGreard Actualizado. ¡Gracias!
Anuj Gupta

3
Dejé de intentarlo y usé esto.
laffuste

Esto funcionó para mí, mientras que ninguna de las respuestas de mayor rango lo hizo.
Jonathan Hartley

@AnujGupta a menudo también manage.py reset_dbnecesita el indicador `-c, --close-sessions` para cerrar las conexiones de la base de datos antes de eliminar la base de datos (solo PostgreSQL)
Valery Ramusik

34

Si está utilizando el paquete South para manejar las migraciones de la base de datos (muy recomendado), entonces puede usar el ./manage.py migrate appname zerocomando.

De lo contrario, recomendaría el ./manage.py dbshellcomando, canalizando comandos SQL en la entrada estándar.


+1. Cualquier proyecto de Django no trivial debería usar South. Y una vez que use South, migrar a Zero es una buena forma idiomática de eliminar todas las tablas.
Manoj Govindan

Incluso los proyectos triviales de Django deberían considerar South. Solo para que la gente se acostumbre a migrar bases de datos, y para que no aprendan malos hábitos como intentar volcar, piratear y recargar datos a mano, o usar el mecanismo de accesorios para migrar datos.
Mike DeSimone

Utilizo South, pero no me molesto en escribir migraciones inversas para cada migración: no menos migraciones de datos. Y no haría eso solo para poder usar la opción cero. Ciertamente, una buena forma de probar que usted / puede / revertir a cero, si eso es importante para usted. Dejar caer todas las mesas me parece razonable.
tobych

26

python manage.py migrate <app> zero

sqlclear se eliminó de 1.9.

Las notas de la versión mencionan que se debe a la introducción de migraciones: https://docs.djangoproject.com/en/1.9/releases/1.9/

Desafortunadamente, no pude encontrar un método que funcione en todas las aplicaciones a la vez, ni una forma incorporada de enumerar todas las aplicaciones instaladas del administrador: ¿Cómo enumerar todas las aplicaciones instaladas con manage.py en Django?

Relacionado: ¿Cómo restablecer las migraciones en Django 1.7?


12

Es mejor usarlo ./manage.py sqlflush | ./manage.py dbshellporque sqlclear requiere que la aplicación se descargue.


7

forma simple (?) de hacerlo desde python (en mysql):

from django.db import connection

cursor = connection.cursor()
cursor.execute('show tables;')
parts = ('DROP TABLE IF EXISTS %s;' % table for (table,) in cursor.fetchall())
sql = 'SET FOREIGN_KEY_CHECKS = 0;\n' + '\n'.join(parts) + 'SET FOREIGN_KEY_CHECKS = 1;\n'
connection.cursor().execute(sql)

5

Si desea borrar completamente la base de datos y resincronizarla de la misma manera, necesita algo como lo siguiente. También combino la adición de datos de prueba en este comando:

#!/usr/bin/env python

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main.settings") # Replace with your app name.

from django.db import connection
from django.core.management import call_command
from django.conf import settings
# If you're using postgres you can't use django's sql stuff for some reason that I
# can't remember. It has to do with that autocommit thing I think.
# import psychodb2 as db

def recreateDb():
    print("Wiping database")
    dbinfo = settings.DATABASES['default']

    # Postgres version
    #conn = db.connect(host=dbinfo['HOST'], user=dbinfo['USER'],
    #                 password=dbinfo['PASSWORD'], port=int(dbinfo['PORT'] or 5432))
    #conn.autocommit = True
    #cursor = conn.cursor()
    #cursor.execute("DROP DATABASE " + dbinfo['NAME'])
    #cursor.execute("CREATE DATABASE " + dbinfo['NAME'] + " WITH ENCODING 'UTF8'") # Default is UTF8, but can be changed so lets be sure.

    # Mysql version:
    print("Dropping and creating database " + dbinfo['NAME'])
    cursor = connection.cursor()
    cursor.execute("DROP DATABASE " + dbinfo["NAME"] + "; CREATE DATABASE " + dbinfo["NAME"] + "; USE " + dbinfo["NAME"] + ";")
    print("Done")


if __name__ == "__main__":
    recreateDb();
    print("Syncing DB")
    call_command('syncdb', interactive=False)
    print("Adding test data")
    addTestData() # ...

Sería bueno poder hacerlo, cursor.execute(call_command('sqlclear', 'main'))pero call_commandimprime el SQL en la salida estándar en lugar de devolverlo como una cadena, y no puedo resolver el sql_deletecódigo ...


Agradable, USE DATABASEle recomiendo que cree un paquete django-recreate-db con un comando de administración que cambiará automáticamente según la configuración para cambiar entre SQLite3 y PostGresql.
Natim

4

Aquí hay un script de shell que terminé juntando para tratar este problema. Espero que le ahorre a alguien algo de tiempo.

#!/bin/sh

drop() {
    echo "Droping all tables prefixed with $1_."
    echo
    echo "show tables" | ./manage.py dbshell |
    egrep "^$1_" | xargs -I "@@" echo "DROP TABLE @@;" |
    ./manage.py dbshell
    echo "Tables dropped."
    echo
}

cancel() {
    echo "Cancelling Table Drop."
    echo
}

if [ -z "$1" ]; then
    echo "Please specify a table prefix to drop."
else
    echo "Drop all tables with $1_ prefix?"
    select choice in drop cancel;do
        $choice $1
        break
    done
fi

1

Usando Python para hacer un comando flushproject, usa:

from django.db import connection
cursor = connection.cursor()
cursor.execute(“DROP DATABASE %s;”, [connection.settings_dict['NAME']])
cursor.execute(“CREATE DATABASE %s;”, [connection.settings_dict['NAME']])

Mi pregunta es cómo realizar esto si la base de datos aún no existe.
Natim

Lamentablemente, cualquier otra acción en el mismo script (por ejemplo, syncdb) dará como resultado errores de "No hay base de datos seleccionada".
Timmmm

Hizo un comando flushdby después de lanzar otro comando. si lo necesita en otro guión, puede usarcall_command
Natim

Yo no sigo. Ya estoy usando call_command. ¿Estás diciendo que debería hacerlo call_command("flushdb")antes call_command("syncdb")?
Timmmm

No funciona. Mismo error. El error es "No se ha seleccionado ninguna base de datos", por lo que no puede ejecutar ningún SQL. Encontré la solución: vea mi otra respuesta.
Timmmm

1

El comando ./manage.py sqlclearo ./manage.py sqlflushparece despejar la mesa y no eliminarlos, por eso si usted quiere eliminar la base de datos completa intente esto: manage.py flush.

Advertencia: esto eliminará su base de datos por completo y perderá todos sus datos, así que si eso no es importante, continúe y pruébelo.


2
No, esto es incorrecto. flush y sqlflush es lo mismo, elimina todos los datos, pero no elimina las tablas. sqlflush muestra el sql, pero no se ejecuta, flush lo ejecuta sin mostrarlo.
Moulde

1

Aquí hay un ejemplo de Makefile para hacer algunas cosas agradables con varios archivos de configuración:

test:
    python manage.py test --settings=my_project.test

db_drop:
    echo 'DROP DATABASE my_project_development;' | ./manage.py dbshell
    echo 'DROP DATABASE my_project_test;' | ./manage.py dbshell

db_create:
    echo 'CREATE DATABASE my_project_development;' | ./manage.py dbshell
    echo 'CREATE DATABASE my_project_test;' | ./manage.py dbshell

db_migrate:
    python manage.py migrate --settings=my_project.base
    python manage.py migrate --settings=my_project.test

db_reset: db_drop db_create db_migrate

.PHONY: test db_drop db_create db_migrate db_reset

Entonces puedes hacer cosas como: $ make db_reset


1

Esta respuesta es para postgresql DB:

Ejecutar: echo 'gota propiedad de some_user ' | ./manage.py dbshell

NOTA: some_user es el nombre del usuario que utiliza para acceder a la base de datos, consulte el archivo settings.py:

default_database = {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'somedbname',
    'USER': 'some_user',
    'PASSWORD': 'somepass',
    'HOST': 'postgresql',
    'PORT': '',
}

1

Si está utilizando psql y tiene django-more 2.0.0 instalado, puede hacerlo

manage.py reset_schema


0

Aquí hay una versión de migración sur de la respuesta de @ peter-g. A menudo jugueteo con sql sin procesar, por lo que esto es útil como 0001_initial.py para cualquier aplicación confusa. Solo funcionará en bases de datos compatibles SHOW TABLES(como mysql). Sustituya algo como SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';si usa PostgreSQL. Además, a menudo hago exactamente lo mismo para las migraciones forwardsy backwards.

from south.db import db
from south.v2 import SchemaMigration
from django.db.utils import DatabaseError
from os import path
from logging import getLogger
logger = getLogger(__name__)


class Migration(SchemaMigration):

    def forwards(self, orm):

        app_name = path.basename(path.split(path.split(path.abspath(__file__))[0])[0])
        table_tuples = db.execute(r"SHOW TABLES;")

        for tt in table_tuples:
            table = tt[0]
            if not table.startswith(app_name + '_'):
                continue
            try:
                logger.warn('Deleting db table %s ...' % table)
                db.delete_table(table)
            except DatabaseError:
                from traceback import format_exc
                logger.error("Error running %s: \n %s" % (repr(self.forwards), format_exc()))

Sin embargo, los compañeros de trabajo / cocoders me matarían si supieran que hice esto.


0

Hay una respuesta aún más simple si desea eliminar TODAS sus tablas. Simplemente vaya a la carpeta que contiene la base de datos (que puede llamarse mydatabase.db), haga clic con el botón derecho en el archivo .db y presione "eliminar". Forma antigua, segura de trabajar.


1
Sin embargo, solo para bases de datos sqlite :-)
winwaed

0

Elimina todas las tablas y las vuelve a crear:

python manage.py sqlclear app1 app2 appN | sed -n "2,$p" | sed -n "$ !p" | sed "s/";/" CASCADE;/" | sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/" | python manage.py dbshell
python manage.py syncdb

Explicación:

manage.py sqlclear - "imprime las instrucciones SQL DROP TABLE para los nombres de aplicaciones dados"

sed -n "2,$p" - toma todas las líneas excepto la primera línea

sed -n "$ !p" - toma todas las líneas excepto la última línea

sed "s/";/" CASCADE;/" - reemplaza todos los puntos y comas (;) con (CASCADE;)

sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/" - inserta (BEGIN;) como primer texto, inserta (COMMIT;) como último texto

manage.py dbshell - "Ejecuta el cliente de línea de comandos para el motor de base de datos especificado en la configuración de ENGINE, con los parámetros de conexión especificados en la configuración de USUARIO, CONTRASEÑA, etc."

manage.py syncdb - "Crea las tablas de la base de datos para todas las aplicaciones en INSTALLED_APPS cuyas tablas aún no se han creado"

Dependencias:


Créditos:

@Manoj Govindan y @Mike DeSimone para sqlclear canalizados a dbshell

@jpic para 'sed "s /"; / "CASCADE; /"'



Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.