Làm cách nào để loại bỏ tất cả các bảng khỏi cơ sở dữ liệu với management.py CLI trong Django?


92

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:


127

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 sqlcleartù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


sqlclear "in các báo cáo thả" nhưng làm thế nào để thực hiện chúng trong đơn gọi dòng lệnh
kmalmur

3
bạn cần tên ứng dụng như:./manage.py sqlclear myAppName | ./manage.py dbshell
Montaro

4
Điều này không hoạt động ở tất cả. sqlclear cần một tên ứng dụng. Tôi đang trên Django 1,8
Jonathan Hartley

1
Chỉ cần lưu ý rằng sqlflush không làm rơi các bảng, nó sẽ cắt ngắn chúng. Ngoài ra, thao tác này có thể sẽ không hoạt động trên DB postgresql của bạn trừ khi bạn thêm từ khóa CASCADE vào cuối lệnh truncate được tạo bởi sqlflush.
user3748764

35

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 sqlclearresetyê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 ).


@JulienGreard Đã cập nhật. Cảm ơn!
Anuj Gupta

3
Tôi đã từ bỏ việc thử và sử dụng cái này.
laffuste

Điều này đã hiệu quả với tôi, trong khi không có câu trả lời nào được xếp hạng cao hơn làm được.
Jonathan Hartley

@AnujGupta cũng thường manage.py reset_dbcầ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ỉ)
Valery Ramusik

34

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 zerolệnh.

Nếu không, tôi khuyên bạn nên dùng ./manage.py dbshelllệnh này, sử dụng lệnh SQL trên đầu vào chuẩn.


+1. Bất kỳ dự án Django không tầm thường nào cũng nên sử dụng South. Và một khi bạn sử dụng South thì chuyển sang Zero là một cách thành ngữ hay để loại bỏ tất cả các bảng.
Manoj Govindan

Ngay cả các dự án Django tầm thường cũng nên xem xét South. Chỉ để mọi người quen với việc di chuyển cơ sở dữ liệu và do đó, họ không học các thói quen xấu như cố gắng đổ, hack và tải lại dữ liệu bằng tay hoặc sử dụng cơ chế cố định để di chuyển dữ liệu.
Mike DeSimone

Tôi sử dụng South, nhưng tôi không bận tâm đến việc viết các phép di chuyển ngược lại cho mỗi lần di chuyển: không nhất là các lần di chuyển dữ liệu. Và tôi sẽ không làm điều đó chỉ để tôi có thể sử dụng tùy chọn số không. Chắc chắn là một cách kiểm tra tốt mà bạn / có thể / đảo ngược ngay trở về 0, nếu điều đó quan trọng đối với bạn. Bỏ tất cả các bàn có vẻ hợp lý với tôi.
tobych

26

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?


12

Tốt hơn là sử dụng ./manage.py sqlflush | ./manage.py dbshellvì sqlclear yêu cầu ứng dụng phải tuôn ra.


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)

5

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_commandin 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_deletemã ...


Rất vui, USE DATABASEtô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.
Natim

4

Đâ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

1

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']])

Câu hỏi của tôi, là làm thế nào để thực hiện điều này nếu cơ sở dữ liệu chưa tồn tại?
Natim 13/12/11

Đáng buồn là bất kỳ hành động nào khác trong cùng một tập lệnh (ví dụ: syncdb) dẫn đến lỗi "Không có cơ sở dữ liệu nào được chọn".
Timmmm

Nó đã thực hiện một lệnh flushdbvà 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
Natim

Tôi không làm theo. Tôi đã sử dụng call_command. Bạn đang nói tôi nên làm gì call_command("flushdb")trước đây call_command("syncdb")?
Timmmm

Không hoạt động. Cùng một lỗi. Lỗi là "Không có cơ sở dữ liệu nào được chọn" nên bạn không thể thực thi bất kỳ SQL nào . Tìm thấy giải pháp: Xem câu trả lời khác của tôi.
Timmmm

1

Lệnh ./manage.py sqlclearhoặc ./manage.py sqlflushdườ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ó.


2
Không, điều này không chính xác. flush và sqlflush giống nhau, nó loại bỏ tất cả dữ liệu, nhưng không làm rơi bảng. sqlflush hiển thị sql, nhưng không thực thi, tuôn ra thực thi nó mà không hiển thị nó.
Moulde

1

Đâ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


1

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': '',
}

1

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


0

Đâ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 forwardsbackwardsdi 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.


0

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.


1
Chỉ dành cho cơ sở dữ liệu sqlite :-)
winwaed

0

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; /"'


0

sử dụng lệnh "python management.py sqlflush" trong windows 10 đối với những người khác gõ management.py


bạn muốn nói gì??
tannu yadav

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.