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?
Jawaban:
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 sqlclear
opsi 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
./manage.py sqlclear myAppName | ./manage.py dbshell
Tidak ada perintah manajemen Django asli untuk melepaskan semua tabel. Keduanya sqlclear
dan reset
membutuhkan 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).
manage.py reset_db
membutuhkan flag `-c, --close-session` untuk menutup koneksi database sebelum menghapus database (hanya PostgreSQL)
Jika Anda menggunakan paket South untuk menangani migrasi database (sangat disarankan), Anda cukup menggunakan ./manage.py migrate appname zero
perintah.
Jika tidak, saya akan merekomendasikan ./manage.py dbshell
perintah, menyalurkan perintah SQL pada input standar.
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?
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)
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_command
mencetak SQL ke stdout daripada mengembalikannya sebagai string, dan saya tidak dapat mengerjakan sql_delete
kodenya ...
USE DATABASE
saya menyarankan Anda untuk membuat paket django-rekreate-db dengan perintah manajemen yang akan otomatis beralih berdasarkan pengaturan untuk beralih antara SQLite3 et PostGresql.
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
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']])
flushdb
dan setelah saya meluncurkan perintah lain. jika Anda membutuhkannya di skrip lain, Anda dapat menggunakancall_command
call_command
. Anda mengatakan saya harus melakukan call_command("flushdb")
sebelumnya call_command("syncdb")
?
Perintah ./manage.py sqlclear
atau ./manage.py sqlflush
tampaknya 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.
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
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': '',
}
Jika Anda menggunakan psql dan menginstal django-more 2.0.0, Anda dapat melakukannya
manage.py reset_schema
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 forwards
dan 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.
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; /"'
gunakan perintah "python manage.py sqlflush" di windows 10 untuk yang lain ketik manage.py
Saya akan merekomendasikan Anda untuk menginstal django-extensions dan menggunakan python manage.py reset_db
perintah. Itu persis seperti yang Anda inginkan.