Як я можу скинути всі таблиці з бази даних за допомогою manage.py та командного рядка? Чи є спосіб зробити це, виконуючи manage.py з відповідними параметрами, щоб я міг виконати його з програми .NET?
Відповіді:
Наскільки я знаю, не існує команди управління, щоб скинути всі таблиці. Якщо ви не проти зламати Python, ви можете написати власну команду для цього. Вам може бути sqlclear
цікавий варіант. Документація говорить, що ./manage.py sqlclear
друкує оператори DROP TABLE SQL для вказаних імен додатка.
Оновлення : Безсоромно привласнюючи коментар @Mike DeSimone під цією відповіддю, щоб дати повну відповідь.
./manage.py sqlclear | ./manage.py dbshell
Станом на django 1.9 це зараз ./manage.py sqlflush
./manage.py sqlclear myAppName | ./manage.py dbshell
Немає власної команди управління Django, щоб скинути всі таблиці. І те, sqlclear
і reset
інше вимагає імені програми.
Тим не менш, ви можете встановити розширення Django, яке надає вам manage.py reset_db
, що робить саме те, що ви хочете (і дає вам доступ до багатьох інших корисних команд управління).
manage.py reset_db
потребує прапорця `-c, --close-session`, щоб закрити з'єднання з базою даних перед тим, як скинути базу даних (лише для PostgreSQL)
Якщо ви використовуєте пакет South для обробки міграцій бази даних (настійно рекомендується), тоді ви можете просто скористатися ./manage.py migrate appname zero
командою.
В іншому випадку я б порекомендував ./manage.py dbshell
команду, перетворюючи команди SQL на стандартний ввід.
python manage.py migrate <app> zero
sqlclear
було вилучено з 1.9.
У примітках до випуску згадується, що це пов'язано з впровадженням міграцій: https://docs.djangoproject.com/en/1.9/releases/1.9/
На жаль, я не зміг знайти метод, який працює на всіх програмах одночасно, ані вбудований спосіб перерахування всіх встановлених програм від адміністратора: Як перерахувати всі встановлені програми за допомогою manage.py в Django?
Пов’язане: Як скинути міграції в Django 1.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)
Якщо ви хочете повністю стерти базу даних та повторно її синхронізувати, потрібно щось на зразок наступного. Я також поєдную додавання тестових даних у цій команді:
#!/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
я рекомендую вам створити пакет django-recreate-db з командою управління, яка автоматично переключатиметься на основі налаштувань для перемикання між SQLite3 та PostGresql.
Ось сценарій оболонки, який я закінчив складати разом, щоб вирішити цю проблему. Сподіваюся, це економить час.
#!/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
Використовуючи 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']])
flushdb
і після того, як я запустив іншу команду. якщо вам це потрібно в іншому сценарії, ви можете використовуватиcall_command
call_command
. Ви кажете, що я мав би це робити call_command("flushdb")
раніше call_command("syncdb")
?
Команда ./manage.py sqlclear
або ./manage.py sqlflush
здається, очистити таблицю і не видаляти їх, однак , якщо ви хочете видалити повну базу даних , спробуйте наступне: manage.py flush
.
Попередження: це повністю видалить вашу базу даних, і ви втратите всі свої дані, тому, якщо це не важливо, спробуйте.
Ось приклад 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
Ця відповідь стосується БД postgresql:
Виконати: echo 'drop, яким володіє some_user ' | ./manage.py dbshell
ПРИМІТКА: some_user - це ім'я користувача, якого ви використовуєте для доступу до бази даних, див. Файл settings.py:
default_database = {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'somedbname',
'USER': 'some_user',
'PASSWORD': 'somepass',
'HOST': 'postgresql',
'PORT': '',
}
Якщо ви використовуєте psql і встановили django-more 2.0.0, ви можете це зробити
manage.py reset_schema
Ось південна версія міграції відповіді @ peter-g. Я часто возиться з raw sql, тому це стає в нагоді як 0001_initial.py для будь-яких заплутаних програм. Це буде працювати лише на БД, які підтримують SHOW TABLES
(наприклад, mysql). Замініть щось на зразок, SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
якщо ви використовуєте PostgreSQL. Крім того, я часто роблю це саме те саме, що стосується forwards
і 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()))
Однак колеги / кодери вбили б мене, якби знали, що я це зробив.
Є ще простіша відповідь, якщо ви хочете видалити ВСІ таблиці. Ви просто перейдете до папки, що містить базу даних (яку можна назвати mydatabase.db), і клацніть правою кнопкою миші файл .db і натисніть "видалити". Старомодний спосіб, впевнено працювати.
Відкидає всі таблиці та відтворює їх:
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, таблиці яких ще не створені"
Залежності:
Кредити:
@Manoj Govindan та @Mike DeSimone для sqlclear, підведеного до dbshell
@jpic для 'sed "s /"; / "CASCADE; /"'
використовуйте команду "python manage.py sqlflush" у Windows 10 для інших типів manage.py
Я б порадив вам встановити розширення django і скористатися python manage.py reset_db
командою. Він робить саме те, що ви хочете.