Làm cách nào để loại bỏ tất cả các bảng khỏi cơ sở dữ liệu bằng cách sử dụng management.py và dòng lệnh? Có cách nào để thực hiện việc thực thi management.py với các tham số thích hợp để tôi có thể thực thi nó từ ứng dụng .NET không?
Câu trả lời:
Theo như tôi biết không có lệnh quản lý để bỏ tất cả các bảng. Nếu bạn không ngại hack Python, bạn có thể viết lệnh tùy chỉnh của riêng mình để làm điều đó. Bạn có thể thấy sqlclear
tùy chọn thú vị. Tài liệu nói rằng ./manage.py sqlclear
In câu lệnh SQL DROP TABLE cho (các) tên ứng dụng đã cho.
Cập nhật : Không biết xấu hổ chiếm đoạt bình luận của @Mike DeSimone bên dưới câu trả lời này để đưa ra câu trả lời đầy đủ.
./manage.py sqlclear | ./manage.py dbshell
Kể từ django 1.9, nó bây giờ ./manage.py sqlflush
./manage.py sqlclear myAppName | ./manage.py dbshell
Không có lệnh quản lý Django gốc nào để loại bỏ tất cả các bảng. Cả hai sqlclear
và reset
yêu cầu một tên ứng dụng.
Tuy nhiên, bạn có thể cài đặt Tiện ích mở rộng Django cung cấp cho bạn manage.py reset_db
, thực hiện chính xác những gì bạn muốn (và cho phép bạn truy cập vào nhiều lệnh quản lý hữu ích hơn ).
manage.py reset_db
cần cờ '-c, --close-sessions` để kết nối cơ sở dữ liệu chặt chẽ trước khi thả cơ sở dữ liệu (PostgreSQL chỉ)
Nếu bạn đang sử dụng gói South để xử lý việc di chuyển cơ sở dữ liệu (rất khuyến khích), thì bạn có thể chỉ cần sử dụng ./manage.py migrate appname zero
lệnh.
Nếu không, tôi khuyên bạn nên dùng ./manage.py dbshell
lệnh này, sử dụng lệnh SQL trên đầu vào chuẩn.
python manage.py migrate <app> zero
sqlclear
đã bị xóa khỏi 1.9.
Ghi chú phát hành đề cập rằng đó là do sự ra đời của quá trình di chuyển: https://docs.djangoproject.com/en/1.9/releases/1.9/
Rất tiếc, tôi không thể tìm thấy một phương pháp hoạt động trên tất cả các ứng dụng cùng một lúc, cũng như một cách tích hợp để liệt kê tất cả các ứng dụng đã cài đặt từ quản trị viên: Làm cách nào để liệt kê tất cả các ứng dụng đã cài đặt với management.py trong Django?
Liên quan: Làm thế nào để đặt lại di chuyển trong Django 1.7?
cách đơn giản (?) để làm điều đó từ python (trên 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)
Nếu bạn muốn xóa hoàn toàn cơ sở dữ liệu và đồng bộ hóa nó trong cùng một lúc, bạn cần một cái gì đó như sau. Tôi cũng kết hợp thêm dữ liệu thử nghiệm trong lệnh này:
#!/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() # ...
Thật tuyệt nếu có thể thực hiện cursor.execute(call_command('sqlclear', 'main'))
nhưng call_command
in SQL ra stdout thay vì trả về nó dưới dạng một chuỗi và tôi không thể tìm ra sql_delete
mã ...
USE DATABASE
tôi khuyên bạn nên tạo một gói django-recreate-db với một lệnh quản lý sẽ tự động chuyển đổi dựa trên cài đặt để chuyển đổi giữa SQLite3 và PostGresql.
Đây là một tập lệnh shell mà tôi đã kết thúc với nhau để giải quyết vấn đề này. Hy vọng nó tiết kiệm cho ai đó một thời gian.
#!/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
Sử dụng Python để tạo một lệnh flushproject, bạn sử dụng:
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
và sau khi tôi khởi chạy một lệnh khác. nếu bạn cần nó trong kịch bản khác, bạn có thể sử dụngcall_command
call_command
. Bạn đang nói tôi nên làm gì call_command("flushdb")
trước đây call_command("syncdb")
?
Lệnh ./manage.py sqlclear
hoặc ./manage.py sqlflush
dường như xóa bảng và không xóa chúng, tuy nhiên nếu bạn muốn xóa cơ sở dữ liệu hoàn chỉnh thử điều này: manage.py flush
.
Cảnh báo: điều này sẽ xóa hoàn toàn cơ sở dữ liệu của bạn và bạn sẽ mất tất cả dữ liệu của mình, vì vậy nếu điều đó không quan trọng, hãy tiếp tục và thử nó.
Đây là một Makefile ví dụ để thực hiện một số điều hay với nhiều tệp cài đặt:
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
Sau đó, bạn có thể làm những việc như:
$ make db_reset
Câu trả lời này dành cho postgresql DB:
Run: echo 'drop by some_user ' | ./manage.py dbshell
LƯU Ý: some_user là tên của người dùng bạn sử dụng để truy cập cơ sở dữ liệu, xem tệp settings.py:
default_database = {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'somedbname',
'USER': 'some_user',
'PASSWORD': 'somepass',
'HOST': 'postgresql',
'PORT': '',
}
Nếu bạn đang sử dụng psql và đã cài đặt django-more 2.0.0, bạn có thể
manage.py reset_schema
Đây là phiên bản di cư về phía nam của câu trả lời của @ peter-g. Tôi thường loay hoay với sql thô, vì vậy điều này rất hữu ích dưới dạng 0001_initial.py cho bất kỳ ứng dụng bị xáo trộn nào. Nó sẽ chỉ hoạt động trên các DB có hỗ trợ SHOW TABLES
(như mysql). Thay thế một cái gì đó như SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
nếu bạn sử dụng PostgreSQL. Ngoài ra, tôi thường làm chính xác điều này cho cả di chuyển forwards
và backwards
di cư.
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()))
Mặc dù vậy, đồng nghiệp / cocoders sẽ giết tôi nếu họ biết tôi đã làm điều này.
Có một câu trả lời thậm chí còn đơn giản hơn nếu bạn muốn xóa TẤT CẢ các bảng của mình. Bạn chỉ cần đi đến thư mục chứa cơ sở dữ liệu (có thể được gọi là mydatabase.db) và nhấp chuột phải vào tệp .db và nhấn "xóa". Cách cũ, chắc chắn để làm việc.
Bỏ tất cả các bảng và tạo lại chúng:
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
Giải trình:
manage.py sqlclear
- "in các câu lệnh SQL DROP TABLE cho (các) tên ứng dụng đã cho"
sed -n "2,$p"
- lấy tất cả các dòng ngoại trừ dòng đầu tiên
sed -n "$ !p"
- lấy tất cả các dòng trừ dòng cuối cùng
sed "s/";/" CASCADE;/"
- thay thế tất cả các dấu chấm phẩy (;) bằng (CASCADE;)
sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/"
- chèn (BEGIN;) làm văn bản đầu tiên, chèn (COMMIT;) làm văn bản cuối cùng
manage.py dbshell
- "Chạy máy khách dòng lệnh cho công cụ cơ sở dữ liệu được chỉ định trong cài đặt ENGINE của bạn, với các tham số kết nối được chỉ định trong cài đặt USER, PASSWORD, v.v."
manage.py syncdb
- "Tạo bảng cơ sở dữ liệu cho tất cả các ứng dụng trong INSTALLED_APPS có bảng chưa được tạo"
Sự phụ thuộc:
Tín dụng:
@Manoj Govindan và @Mike DeSimone cho sqlclear được chuyển sang dbshell
@jpic cho 'sed "s /"; / "CASCADE; /"'
sử dụng lệnh "python management.py sqlflush" trong windows 10 đối với những người khác gõ management.py
Tôi khuyên bạn nên cài đặt phần mở rộng django và sử dụng python manage.py reset_db
lệnh. Nó làm chính xác những gì bạn muốn.