Як я можу скинути всі таблиці з бази даних за допомогою 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командою. Він робить саме те, що ви хочете.