Djangoのmanage.py CLIでデータベースからすべてのテーブルを削除する方法は?


92

manage.pyとコマンドラインを使用してデータベースからすべてのテーブルを削除するにはどうすればよいですか?.NETアプリケーションから実行できるように、適切なパラメーターでmanage.pyを実行する方法はありますか?

回答:


127

私の知る限り、すべてのテーブルを削除する管理コマンドはありません。Pythonのハッキングを気にしない場合は、独自のカスタムコマンドを記述してそれを行うことができます。このsqlclearオプションは興味深いかもしれません。ドキュメントには./manage.py sqlclear 、指定されたアプリ名のDROP TABLE SQLステートメントが出力されると記載されています。

更新:この回答の下にある@Mike DeSimoneのコメントを恥知らずに流用して完全な回答を提供します。

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

django 1.9の時点で ./manage.py sqlflush


sqlclearは "dropステートメントを出力します"が、それらを単一のコマンドライン呼び出しで実行する方法
kmalmur

3
あなたのようなアプリ名を必要とする:./manage.py sqlclear myAppName | ./manage.py dbshell
とMontaro

4
これはまったく機能しません。sqlclearにはアプリ名が必要です。私はDjango 1.8を使用しています
Jonathan Hartley

sqlflushはテーブルを削除せず、テーブルを切り捨てることに注意してください。また、sqlflushによって生成された切り捨てコマンドの最後にCASCADEキーワードを追加しない限り、この操作はおそらくpostgresql DBでは機能しません。
user3748764

35

すべてのテーブルを削除するネイティブのDjango管理コマンドはありません。どちらsqlclearresetアプリ名が必要です。

ただし、Django Extensionsをインストールして、必要な機能manage.py reset_db正確に実行できます(さらに多くの便利な管理コマンドにアクセスできます)。


@JulienGreard更新されました。ありがとう!
Anuj Gupta 14年

3
私はこれを試してあきらめて、これを使いました。
laffuste 2014

これは私にとってはうまくいきましたが、上位の回答はどれもうまくいきませんでした。
Jonathan Hartley

@AnujGuptaはmanage.py reset_db、データベースをドロップする前にデータベース接続を閉じるためにフラグ `-c、--close-sessions` もしばしば 必要です(PostgreSQLのみ)
Valery Ramusik

34

Southパッケージを使用してデータベースの移行を処理する場合(強く推奨)、./manage.py migrate appname zeroコマンドを使用するだけで済みます。

それ以外の場合は、./manage.py dbshell標準入力でSQLコマンドをパイプインするコマンドをお勧めします。


+1。重要なDjangoプロジェクトでは、Southを使用する必要があります。また、Southを使用してからZeroに移行することは、すべてのテーブルを削除する慣用的な方法です。
Manoj Govindan 2013年

些細なDjangoプロジェクトでさえ南を考慮すべきです。人々がデータベースの移行に慣れるために、手作業でデータをダンプ、ハッキング、リロードしたり、フィクスチャメカニズムを使用してデータを移行したりするような悪い習慣を学ばないようにします。
Mike DeSimone 2013年

私はSouthを使用していますが、すべての移行について逆移行を作成する必要はありません。データ移行は特に重要です。そして、ゼロオプションを使用できるように、私はそれをしません。それがあなたにとって重要であるなら、あなたがゼロに戻ることができる/できる/逆にすることをテストする確かな良い方法。すべてのテーブルを削除することは、私には理にかなっているようです。
tobych

26

python manage.py migrate <app> zero

sqlclear 1.9から削除されました。

リリースノートには、移行の導入が原因であると記載されていますhttps : //docs.djangoproject.com/en/1.9/releases/1.9/

残念ながら、すべてのアプリで一度に機能するメソッドも、インストール済みのすべてのアプリを管理者から一覧表示する組み込みの方法も見つかりませんでした。Djangoでmanage.pyを使用してすべてのインストール済みアプリを一覧表示する方法はありませんか。

関連:Django 1.7で移行をリセットする方法


12

./manage.py sqlflush | ./manage.py dbshellsqlclearではアプリがフラッシュする必要があるため、使用することをお勧めします。


7

python(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

データベースを完全にワイプして再同期する場合は、次のようなものが必要です。このコマンドでは、テストデータの追加も組み合わせています。

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

できればいいのですcursor.execute(call_command('sqlclear', 'main'))call_command、SQLを文字列として返すのではなく、stdoutに出力しsql_deleteます。コードを理解できません...


ニースUSE DATABASE私は設定に基づいて意志のオートスイッチは、SQLite3の他のPostgreSQLを切り替えるには管理コマンドとジャンゴ・再作成-DBパッケージを作成することができrecommand。
Natim

4

これが、この問題に対処するためにまとめたシェルスクリプトです。誰かの時間を節約してくれることを願っています。

#!/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

Pythonを使用してflushprojectコマンドを作成するには、以下を使用します。

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

残念ながら、同じスクリプト(syncdbなど)でさらにアクションを実行すると、「データベースが選択されていません」というエラーが発生します。
Timmmm

コマンドflushdbを実行した後、別のコマンドを起動しました。別のスクリプトで必要な場合は、次のように使用できますcall_command
Natim

私はついていません。私はすでに使用していcall_commandます。私はcall_command("flushdb")前にやるべきだと言ってるのcall_command("syncdb")
Timmmm

動作しません。同じエラー。エラーは「データベースが選択されていません」であるため SQLを実行できません。解決策を見つけた:私の他の答えを見てください。
Timmmm

1

コマンド./manage.py sqlclearまたは./manage.py sqlflushあなたが完全なデータベースを削除したい場合はしかし、テーブルをクリアし、それらを削除しないように見えるが、これを試してみてくださいmanage.py flush

警告: これによりデータベースが完全に削除され、すべてのデータが失われるため、それが重要でない場合は先に進んでみてください。


2
いいえ、不正解です。flushとsqlflushは同じです。すべてのデータが削除されますが、テーブルは削除されません。sqlflushはsqlを表示しますが、実行しません。flushは表示せずに実行します。
Moulde

1

以下は、複数の設定ファイルを使用していくつかの素晴らしいことを行うMakefileの例です。

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

その後、次のようなことができます: $ make db_reset


1

この回答はpostgresql DB用です:

実行:echo 'drop所有のsome_user ' | ./manage.py dbshel​​l

注:some_userは、データベースへのアクセスに使用するユーザーの名前です。settings.pyファイルを参照してください。

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


0

これは@ peter-gの回答の南移行バージョンです。私はしばしば生のsqlをいじるので、これは困惑したアプリの0001_initial.pyとして役に立ちます。これは、SHOW TABLES(mysqlなど)をサポートするDBでのみ機能します。SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';PostgreSQLを使用する場合のように置き換えます。また、forwardsbackwardsマイグレーションの両方で、これとまったく同じことをよく行います。

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()))

同僚/コーダーは、私がそうしていることを知っていれば私を殺すでしょう。


0

テーブルをすべて削除したい場合は、もっと簡単な答えがあります。データベースを含むフォルダー(mydatabase.dbと呼ばれることもあります)に移動し、.dbファイルを右クリックして[削除]を押すだけです。昔ながらの方法で、確実に機能します。


1
ただし、sqliteデータベースの場合のみ:-)
2013

0

すべてのテーブルを削除して再作成します。

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

説明:

manage.py sqlclear -"指定されたアプリ名のDROP TABLE SQLステートメントを出力します"

sed -n "2,$p" -最初の行を除くすべての行を取得します

sed -n "$ !p" -最後の行を除くすべての行を取得します

sed "s/";/" CASCADE;/" -すべてのセミコロン(;)を(CASCADE;)に置き換えます

sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/" -最初のテキストとして(BEGIN;)を挿入し、最後のテキストとして(COMMIT;)を挿入します

manage.py dbshell -「ENGINE設定で指定されたデータベースエンジンのコマンドラインクライアントを実行し、USER、PASSWORDなどの設定で指定された接続パラメーターを使用します」

manage.py syncdb -「テーブルがまだ作成されていないINSTALLED_APPSのすべてのアプリのデータベーステーブルを作成します」

依存関係:


クレジット:

sqlclearの@Manoj Govindanと@Mike DeSimoneがdbshel​​lにパイプ接続

@sic "s /"; / "CASCADE; /"の@jpic



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.