2010-08-05 9 views

Respuesta

112

Hasta donde sé, no hay ningún comando de administración para eliminar todas las tablas. Si no te importa piratear Python, puedes escribir tu propio comando personalizado para hacerlo. Puede encontrar la opción sqlclear interesante. La documentación dice que ./manage.py sqlclearImprime las sentencias SQL DROP TABLE para el (los) nombre (s) de aplicación proporcionados.

actualización: apropiarse Desvergonzadamente comentario @Mike DeSimone 's por debajo de esta respuesta que dar una respuesta completa.

./manage.py sqlclear | ./manage.py dbshell 
+0

sqlclear "Imprime las sentencias de caída", pero la forma de ejecutar en la línea de comandos sola llame al – kmalmur

+66

Pipe it to './manage.py dbshell'. –

+7

llamadas sqlclear necesitan un nombre de aplicación. – tobych

28

Si está usando el paquete del Sur para gestionar las migraciones de bases de datos (muy recomendable), a continuación, sólo podría utilizar el comando ./manage.py migrate appname zero.

De lo contrario, me gustaría recomendar el comando ./manage.py dbshell, tuberías de comandos SQL en la entrada estándar.

+0

+1. Cualquier proyecto no trivial de Django debería usar el sur. Y una vez que utilizas el Sur, migrar a Zero es una buena forma idiomática de eliminar todas las tablas. –

+0

Incluso los proyectos triviales de Django deberían considerar el sur. Solo para hacer que la gente se acostumbre a migrar las bases de datos, y para que no aprendan malos hábitos, como tratar de volcar, piratear y volver a cargar datos a mano, o usar el mecanismo de accesorios para migrar datos. –

+0

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

4

Aquí hay un script de shell que terminé reconstruyendo 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 
0

utilizar Python para hacer un comando flushproject, que utilice:

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']]) 
+0

Mi pregunta es cómo realizar esto si la base de datos no existe todavía. – Natim

+0

Lamentablemente, cualquier acción adicional en el mismo script (por ejemplo, syncdb) da como resultado errores "Sin base de datos seleccionada". – Timmmm

+0

Hizo un comando 'flushdb' y después de lanzar otro comando. si lo necesita en otro script, puede usar 'call_command' – Natim

2

Si desea eliminar por completo la base de datos y volver a sincronizar en el mismo vaya usted necesita algo así como lo siguiente. Yo también combinan la adición de los 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 hacer cursor.execute(call_command('sqlclear', 'main')) pero call_command imprime el SQL para la salida estándar en lugar de devolverlo como una cadena, y no puedo calcular el sql_delete código ...

+0

Agradable el 'USE DATABASE' Te recomiendo que crees un paquete django-recreate-db con un comando de administración que cambiará automáticamente en función de la configuración para alternar entre SQLite3 y PostGresql. – Natim

21

no hay comandos nativos de administración de Django para dejar todas las tablas. Tanto sqlclear como reset requieren un nombre de aplicación.

Sin embargo, puede instalar Django Extensions que le da manage.py reset_db, que hace exactamente lo que quiere (y le da acceso a many more comandos de administración útiles). (?)

+0

el enlace "muchos más" está muerto –

+0

@JulienGreard Actualizado. ¡Gracias! –

+1

Dejé de intentarlo y lo usé. – laffuste

5

sencilla manera 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) 
0

Aquí hay una versión migración hacia el sur de la respuesta de @ peter-g. A menudo juego con raw sql, así que esto es útil como 0001_initial.py para cualquier aplicación confundida. Solo funcionará en DB que admitan SHOW TABLES (como mysql). Sustituye algo como SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'; si usas PostgreSQL. Además, a menudo hago exactamente lo mismo para las migraciones forwards y 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())) 

Compañero de trabajo/cocoders me mataría si sabían que hice esto, sin embargo.

0

Hay una respuesta aún más sencillo si desea borrar todas las tablas. Simplemente vaya a su carpeta que contiene la base de datos (que puede llamarse mydatabase.db) y haga clic con el botón derecho en el archivo .db y presione "eliminar". Manera antigua, seguro de trabajar.

+1

Solo para bases de datos sqlite :-) – winwaed

0

Gotas todas las tablas y las recrea:

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 sentencias DROP TABLE de SQL para el nombre dado aplicación (s)"

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

sed -n "$ !p" - agarra al l 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;/" - insertos (COMENZAR;) como primer texto, inserciones (COMMIT;) como último texto

manage.py dbshell - "Ejecuta el cliente de línea de comandos para el motor de base de datos especificado en su configuración ENGINE, con los parámetros de conexión especificados en sus configuraciones USER, PASSWORD, etc."

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

Dependencias:


Créditos:

@Manoj Govindan y @Mike DeSimone para sqlcle ar hilo a dbshell

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

11

Es mejor utilizar ./manage.py sqlflush | ./manage.py dbshell porque sqlclear requiere aplicación para enjuagar.

0

El comando ./manage.py sqlclear o ./manage.py sqlflush parece borrar la tabla y no eliminarlos; sin embargo, si desea eliminar la base de datos completa, intente esto: manage.py flush.

Advertencia:esto borrará completamente su base de datos y perderá todos sus datos, por lo que si no es importante, intentelo.

+1

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

12

python manage.py migrate <app> zero

sqlclear se retiró de 1,9.

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

Desafortunadamente no pude encontrar un método que funciona en todas las aplicaciones a la vez, ni una manera integrada para enumerar todas las aplicaciones instaladas de la admin: How to list all installed apps with manage.py in Django?

relacionadas: How to reset migrations in Django 1.7?

2

Si está utilizando Postgres:

echo 'DROP SCHEMA public CASCADE; CREATE SCHEMA public;' | ./manage.py dbshell 
0

He aquí un ejemplo Makefile para hacer algunas cosas buenas con múltiples 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 

A continuación, puede hacer cosas como: $ make db_reset

Cuestiones relacionadas