Bagaimana membuang semua tabel dari database dengan manage.py CLI di Django?

95

Bagaimana cara menghapus semua tabel dari database menggunakan manage.py dan baris perintah? Apakah ada cara untuk melakukan itu dengan mengeksekusi manage.py dengan parameter yang sesuai sehingga saya dapat menjalankannya dari aplikasi .NET?

kmalmur
sumber

Jawaban:

128

Sejauh yang saya tahu tidak ada perintah manajemen untuk menghapus semua tabel. Jika Anda tidak keberatan meretas Python, Anda dapat menulis perintah khusus Anda sendiri untuk melakukannya. Anda mungkin menganggap sqlclearopsi ini menarik. Dokumentasi mengatakan bahwa ./manage.py sqlclear Mencetak pernyataan DROP TABLE SQL untuk nama aplikasi yang diberikan.

Update : Tanpa malu-malu menggunakan komentar @Mike DeSimone di bawah jawaban ini untuk memberikan jawaban lengkap.

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

Mulai dari django 1.9 sekarang ./manage.py sqlflush

Manoj Govindan
sumber
sqlclear "mencetak pernyataan drop" tetapi bagaimana mengeksekusinya dalam panggilan baris perintah tunggal
kmalmur
3
Anda memerlukan nama aplikasi seperti:./manage.py sqlclear myAppName | ./manage.py dbshell
Montaro
4
Ini tidak bekerja sama sekali. sqlclear membutuhkan nama aplikasi. Saya di Django 1.8
Jonathan Hartley
1
Sadarilah bahwa sqlflush tidak menjatuhkan tabel, itu memotongnya. Juga operasi ini mungkin tidak akan berfungsi pada DB postgresql Anda kecuali Anda menambahkan kata kunci CASCADE di akhir perintah truncate yang dihasilkan oleh sqlflush.
pengguna3748764
39

Tidak ada perintah manajemen Django asli untuk melepaskan semua tabel. Keduanya sqlcleardan resetmembutuhkan nama aplikasi.

Akan tetapi, Anda dapat memasang Ekstensi Django yang memberi Anda manage.py reset_db, yang melakukan apa yang Anda inginkan (dan memberi Anda akses ke lebih banyak perintah manajemen yang berguna).

Anuj Gupta
sumber
@JulienGard Diperbarui. Terima kasih!
Anuj Gupta
4
Saya berhenti mencoba dan menggunakan ini.
laffuste
Ini berhasil untuk saya, sementara tidak ada jawaban dengan peringkat lebih tinggi yang berhasil.
Jonathan Hartley
1
@AnujGupta juga sering manage.py reset_dbmembutuhkan flag `-c, --close-session` untuk menutup koneksi database sebelum menghapus database (hanya PostgreSQL)
Valery Ramusik
34

Jika Anda menggunakan paket South untuk menangani migrasi database (sangat disarankan), Anda cukup menggunakan ./manage.py migrate appname zeroperintah.

Jika tidak, saya akan merekomendasikan ./manage.py dbshellperintah, menyalurkan perintah SQL pada input standar.

Mike DeSimone
sumber
+1. Proyek Django non-sepele apapun harus menggunakan Selatan. Dan setelah Anda menggunakan Selatan, lalu bermigrasi ke Nol adalah cara idiomatik yang bagus untuk menghapus semua tabel.
Manoj Govindan
Bahkan proyek Django yang sepele harus mempertimbangkan Selatan. Hanya untuk membuat orang terbiasa dengan migrasi database, sehingga mereka tidak mempelajari kebiasaan buruk seperti mencoba membuang, meretas, dan memuat ulang data dengan tangan, atau menggunakan mekanisme perlengkapan untuk memigrasi data.
Mike DeSimone
Saya memang menggunakan Selatan, tapi saya tidak repot-repot menulis migrasi terbalik untuk setiap migrasi: paling tidak migrasi data. Dan saya tidak akan melakukannya hanya agar saya dapat menggunakan opsi nol. Tentunya cara yang baik untuk menguji bahwa Anda / dapat / membalikkan kembali ke nol, jika itu penting bagi Anda. Menjatuhkan semua tabel tampaknya masuk akal bagi saya.
tobych
26

python manage.py migrate <app> zero

sqlclear telah dihapus dari 1.9.

Catatan rilis menyebutkan bahwa ini karena pengenalan migrasi: https://docs.djangoproject.com/en/1.9/releases/1.9/

Sayangnya saya tidak dapat menemukan metode yang bekerja pada semua aplikasi sekaligus, atau cara bawaan untuk mendaftar semua aplikasi yang diinstal dari admin: Bagaimana cara mendaftar semua aplikasi yang diinstal dengan manage.py di Django?

Terkait: Bagaimana mengatur ulang migrasi di Django 1.7?

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
12

Lebih baik digunakan ./manage.py sqlflush | ./manage.py dbshellkarena sqlclear membutuhkan aplikasi untuk menyiram.

FeroxTL
sumber
7

cara sederhana (?) untuk melakukannya dari python (di 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)
lemanyk
sumber
5

Jika Anda ingin sepenuhnya menghapus database dan menyinkronkannya kembali dalam waktu yang sama, Anda memerlukan sesuatu seperti berikut ini. Saya juga menggabungkan penambahan data uji dalam perintah ini:

#!/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() # ...

Alangkah baiknya bisa melakukannya cursor.execute(call_command('sqlclear', 'main'))tetapi call_commandmencetak SQL ke stdout daripada mengembalikannya sebagai string, dan saya tidak dapat mengerjakan sql_deletekodenya ...

Timmmm
sumber
Senang USE DATABASEsaya menyarankan Anda untuk membuat paket django-rekreate-db dengan perintah manajemen yang akan otomatis beralih berdasarkan pengaturan untuk beralih antara SQLite3 et PostGresql.
Natim
4

Berikut adalah skrip shell yang akhirnya saya kumpulkan untuk menangani masalah ini. Semoga bisa menghemat waktu seseorang.

#!/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
Peter G
sumber
1

Menggunakan Python untuk membuat perintah flushproject, Anda menggunakan:

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']])
Natim
sumber
Pertanyaan saya, adalah bagaimana melakukan ini jika database belum ada?
Natim
Sayangnya tindakan lebih lanjut dalam skrip yang sama (misalnya syncdb) menghasilkan kesalahan "Tidak ada database yang dipilih".
Timmmm
Itu melakukan perintah flushdbdan setelah saya meluncurkan perintah lain. jika Anda membutuhkannya di skrip lain, Anda dapat menggunakancall_command
Natim
Saya tidak mengikuti. Saya sudah menggunakan call_command. Anda mengatakan saya harus melakukan call_command("flushdb")sebelumnya call_command("syncdb")?
Timmmm
Tidak berhasil. Kesalahan yang sama. Kesalahannya adalah "Tidak ada database yang dipilih" sehingga Anda tidak dapat menjalankan SQL apa pun . Menemukan solusinya: Lihat jawaban saya yang lain.
Timmmm
1

Perintah ./manage.py sqlclearatau ./manage.py sqlflushtampaknya untuk membersihkan meja dan tidak menghapusnya, namun jika Anda ingin menghapus database yang lengkap coba ini: manage.py flush.

Peringatan: ini akan menghapus database Anda sepenuhnya dan Anda akan kehilangan semua data Anda, jadi jika itu tidak penting, lanjutkan dan coba.

iyogeshjoshi
sumber
2
Tidak, ini salah. flush dan sqlflush adalah sama, ini menghapus semua data, tetapi tidak menjatuhkan tabel. sqlflush menampilkan sql, tetapi tidak mengeksekusi, flush mengeksekusinya tanpa menampilkannya.
Moulde
1

Berikut adalah contoh Makefile untuk melakukan beberapa hal bagus dengan beberapa file pengaturan:

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

Kemudian Anda dapat melakukan hal-hal seperti: $ make db_reset

daino3
sumber
1

Jawaban ini untuk postgresql DB:

Jalankan: echo 'drop milik some_user ' | ./manage.py dbshell

CATATAN: some_user adalah nama pengguna yang Anda gunakan untuk mengakses database, lihat file settings.py:

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

Jika Anda menggunakan psql dan menginstal django-more 2.0.0, Anda dapat melakukannya

manage.py reset_schema

Alice Purcell
sumber
0

Berikut adalah versi migrasi selatan dari jawaban @ peter-g. Saya sering mengutak-atik sql mentah, jadi ini berguna sebagai 0001_initial.py untuk aplikasi apa pun yang membingungkan. Ini hanya akan bekerja pada DB yang mendukung SHOW TABLES(seperti mysql). Gantikan sesuatu seperti SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';jika Anda menggunakan PostgreSQL. Juga, saya sering melakukan hal yang sama persis untuk migrasi forwardsdan 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()))

Rekan kerja / cocoders akan membunuh saya jika mereka tahu saya melakukan ini.

kompor
sumber
0

Ada jawaban yang lebih sederhana jika Anda ingin menghapus SEMUA tabel Anda. Anda cukup pergi ke folder Anda yang berisi database (yang mungkin disebut mydatabase.db) dan klik kanan file .db dan tekan "delete." Cara kuno, pasti berhasil.

Rock Lee
sumber
1
Hanya untuk database sqlite :-)
winwaed
0

Jatuhkan semua tabel dan buat ulang:

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

Penjelasan:

manage.py sqlclear - "mencetak pernyataan DROP TABLE SQL untuk nama aplikasi yang diberikan"

sed -n "2,$p" - meraih semua baris kecuali baris pertama

sed -n "$ !p" - meraih semua baris kecuali baris terakhir

sed "s/";/" CASCADE;/" - mengganti semua titik koma (;) dengan (CASCADE;)

sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/" - menyisipkan (BEGIN;) sebagai teks pertama, menyisipkan (COMMIT;) sebagai teks terakhir

manage.py dbshell - "Menjalankan klien baris perintah untuk mesin database yang ditentukan dalam setelan ENGINE Anda, dengan parameter koneksi yang ditentukan dalam setelan PENGGUNA, KATA SANDI, dll."

manage.py syncdb - "Membuat tabel database untuk semua aplikasi di INSTALLED_APPS yang tabelnya belum dibuat"

Dependensi:


Kredit:

@Manoj Govindan dan @Mike DeSimone untuk sqlclear disalurkan ke dbshell

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

Stephen Cernota
sumber
0

gunakan perintah "python manage.py sqlflush" di windows 10 untuk yang lain ketik manage.py

tannu yadav
sumber
apa yang ingin kamu katakan??
tannu yadav
0

Saya akan merekomendasikan Anda untuk menginstal django-extensions dan menggunakan python manage.py reset_dbperintah. Itu persis seperti yang Anda inginkan.

Diego Aragão
sumber