¿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:
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 sqlclear
opció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
./manage.py sqlclear myAppName | ./manage.py dbshell
No hay un comando de administración nativo de Django para eliminar todas las tablas. Ambos sqlclear
y reset
requieren 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).
manage.py reset_db
necesita el indicador `-c, --close-sessions` para cerrar las conexiones de la base de datos antes de eliminar la base de datos (solo PostgreSQL)
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 zero
comando.
De lo contrario, recomendaría el ./manage.py dbshell
comando, canalizando comandos SQL en la entrada estándar.
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?
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)
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_command
imprime el SQL en la salida estándar en lugar de devolverlo como una cadena, y no puedo resolver el sql_delete
código ...
USE DATABASE
le 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.
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
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']])
flushdb
y después de lanzar otro comando. si lo necesita en otro guión, puede usarcall_command
call_command
. ¿Estás diciendo que debería hacerlo call_command("flushdb")
antes call_command("syncdb")
?
El comando ./manage.py sqlclear
o ./manage.py sqlflush
parece 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.
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
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': '',
}
Si está utilizando psql y tiene django-more 2.0.0 instalado, puede hacerlo
manage.py reset_schema
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 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()))
Sin embargo, los compañeros de trabajo / cocoders me matarían si supieran que hice esto.
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.
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; /"'
use el comando "python manage.py sqlflush" en Windows 10 para otros, escriba manage.py
Te recomendaría que instales django-extensions y uses python manage.py reset_db
command. Hace exactamente lo que quieres.