Respostas:
Pelo que eu sei, não existe um comando de gerenciamento para eliminar todas as tabelas. Se você não se importa em hackear Python, pode escrever seu próprio comando personalizado para fazer isso. Você pode achar a sqlclear
opção interessante. A documentação diz que ./manage.py sqlclear
imprime as instruções DROP TABLE SQL para os nomes de aplicativos fornecidos.
Atualização : Desavergonhadamente apropriando-se do comentário de @Mike DeSimone abaixo desta resposta para dar uma resposta completa.
./manage.py sqlclear | ./manage.py dbshell
No Django 1.9 agora é ./manage.py sqlflush
./manage.py sqlclear myAppName | ./manage.py dbshell
Não há comando de gerenciamento Django nativo para eliminar todas as tabelas. Ambos sqlclear
e reset
exigem um nome de aplicativo.
No entanto, você pode instalar extensões Django que fornecem a você manage.py reset_db
, o que faz exatamente o que você deseja (e fornece acesso a muitos outros comandos de gerenciamento úteis).
manage.py reset_db
precisa do sinalizador `-c, --close-sessions` para fechar as conexões do banco de dados antes de descartar o banco de dados (somente PostgreSQL)
Se você estiver usando o pacote South para lidar com migrações de banco de dados (altamente recomendado), você pode apenas usar o ./manage.py migrate appname zero
comando.
Caso contrário, eu recomendaria o ./manage.py dbshell
comando, canalizando comandos SQL na entrada padrão.
python manage.py migrate <app> zero
sqlclear
foi removido do 1.9.
As notas de lançamento mencionam que é devido à introdução de migrações: https://docs.djangoproject.com/en/1.9/releases/1.9/
Infelizmente, não consegui encontrar um método que funcione em todos os aplicativos ao mesmo tempo, nem uma maneira integrada de listar todos os aplicativos instalados pelo administrador: Como listar todos os aplicativos instalados com manage.py no Django?
Relacionado: Como redefinir migrações no Django 1.7?
maneira simples (?) de fazer isso em python (no 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)
Se você deseja limpar completamente o banco de dados e sincronizá-lo novamente, você precisa de algo como o seguinte. Eu também combino a adição de dados de teste neste 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() # ...
Seria bom poder fazer, cursor.execute(call_command('sqlclear', 'main'))
mas call_command
imprimir o SQL em stdout em vez de retorná-lo como uma string, e eu não consigo descobrir o sql_delete
código ...
USE DATABASE
, recomendo que você crie um pacote django-recreate-db com um comando de gerenciamento que irá alternar automaticamente com base nas configurações para alternar entre SQLite3 e PostGresql.
Aqui está um script de shell que acabei montando para lidar com esse problema. Espero que economize algum tempo.
#!/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 fazer um comando flushproject, você 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
e depois lancei outro comando. se precisar em outro script, você pode usarcall_command
call_command
. Você está dizendo que eu deveria fazer call_command("flushdb")
antes call_command("syncdb")
?
O comando ./manage.py sqlclear
ou ./manage.py sqlflush
parece limpar a mesa e não excluí-los, no entanto, se você deseja excluir o banco de dados completo tente o seguinte: manage.py flush
.
Aviso: isso excluirá seu banco de dados completamente e você perderá todos os seus dados, então se isso não for importante, vá em frente e experimente.
Aqui está um Makefile de exemplo para fazer algumas coisas boas com vários arquivos de configurações:
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
Então você pode fazer coisas como:
$ make db_reset
Esta resposta é para o banco de dados postgresql:
Executar: echo 'drop propriedade de some_user ' | ./manage.py dbshell
NOTA: some_user é o nome do usuário que você usa para acessar o banco de dados, consulte o arquivo settings.py:
default_database = {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'somedbname',
'USER': 'some_user',
'PASSWORD': 'somepass',
'HOST': 'postgresql',
'PORT': '',
}
Se você estiver usando psql e tiver django-more 2.0.0 instalado, você pode fazer
manage.py reset_schema
Aqui está uma versão de migração para o sul da resposta de @peter-g. Costumo brincar com sql bruto, então isso é útil como 0001_initial.py para qualquer aplicativo confuso. Ele só funcionará em bancos de dados que suportam SHOW TABLES
(como o mysql). Substitua por algo como SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
se você usar PostgreSQL. Além disso, geralmente faço exatamente a mesma coisa para as migrações forwards
e 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()))
No entanto, colegas de trabalho / cocodificadores me matariam se soubessem que fiz isso.
Há uma resposta ainda mais simples se você quiser excluir TODAS as suas tabelas. Basta ir para a pasta que contém o banco de dados (que pode ser chamado de mydatabase.db), clicar com o botão direito do mouse no arquivo .db e pressionar "excluir". Maneira antiquada, infalível de trabalhar.
Descarta todas as tabelas e as recria:
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
Explicação:
manage.py sqlclear
- "imprime as instruções SQL DROP TABLE para os nomes de aplicativos fornecidos"
sed -n "2,$p"
- pega todas as linhas, exceto a primeira linha
sed -n "$ !p"
- pega todas as linhas, exceto a última linha
sed "s/";/" CASCADE;/"
- substitui todos os pontos-e-vírgulas (;) por (CASCADE;)
sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/"
- insere (BEGIN;) como primeiro texto, insere (COMMIT;) como último texto
manage.py dbshell
- "Executa o cliente de linha de comando para o mecanismo de banco de dados especificado em sua configuração ENGINE, com os parâmetros de conexão especificados em sua configuração USER, PASSWORD, etc."
manage.py syncdb
- "Cria as tabelas de banco de dados para todos os aplicativos em INSTALLED_APPS cujas tabelas ainda não foram criadas"
Dependências:
Créditos:
@Manoj Govindan e @Mike DeSimone para sqlclear canalizado para dbshell
@jpic para 'sed "s /"; / "CASCADE; /"'
use o comando "python manage.py sqlflush" no Windows 10 para outros, digite manage.py
Eu recomendo que você instale extensões django e usepython manage.py reset_db
comando. Ele faz exatamente o que você deseja.