Django: удалите все данные из каждой таблицы (но сохраните сами таблицы)

Я пытаюсь синхронизировать данные между двумя установками django (производство и тестирование). Я делаю это, используя ./manage.py dumpdata --natural при производстве, а затем ./manage.py loaddata в свежую syncdb 'ed базу данных при тестировании.

Все работало нормально, пока я не добавил новое пользовательское разрешение. Производство syncdb загрузило это новое разрешение в другом порядке (с другим первичным ключом), чем новый syncdb в пустой базе данных. Следовательно, он получает другой идентификатор. Поэтому, несмотря на использование естественных ключей, когда я пытаюсь загрузить данные, я получаю эту ошибку, когда загружается первый объект разрешения вне порядка:

IntegrityError: duplicate key value violates unique constraint "auth_permission_content_type_id_codename_key"

Самый простой способ, с помощью которого я могу исправить это, - удалить все данные из каждой таблицы в тестовой установке, то есть использовать syncdb только для создания таблиц, а также не загружать исходные данные. Но syncdb не позволяет пропустить начальный шаг данных/сигналов. Если вы не указали явное имя каждой модели или таблицы, как я могу удалить все начальные данные после вызова syncdb? Или существует способ создания только пустых таблиц без использования syncdb?

./manage.py flush не то, что мне нужно - он перезагружает исходные данные и запускает сигналы syncdb.

Ответ 1

В соответствии с помощью команды flush (я использую Django 1.3.1) SQL, который выполняется, - это тот же SQL, полученный из ./manage.py sqlflush, а затем переустанавливаются исходные данные.

$ python manage.py help flush 
Usage: manage.py flush [options]

Executes ``sqlflush`` on the current database.

Чтобы получить те же самые возможности очистки данных за вычетом загрузки прибора, вы можете получить SQL, вызвав ./manage.py sqlflush, а затем выполнить этот SQL с помощью встроенной поддержки Django для выполнения произвольного SQL:

from django.core.management import call_command, setup_environ
from your_django_project import settings
setup_environ(settings)

from django.db import connection
from StringIO import StringIO

def main():
    # 'call' manage.py flush and capture its outputted sql
    command_output = StringIO()
    call_command("sqlflush", stdout=command_output)

    command_output.seek(0)
    flush_sql = command_output.read()

    # execute the sql
    # from: https://docs.djangoproject.com/en/dev/topics/db/sql/#executing-custom-sql-directly
    cursor = connection.cursor()
    cursor.execute(flush_sql)

    print "db has been reset"

if __name__ == '__main__':
    main()

Это имеет дополнительное преимущество, которое вы можете изменить SQL из ./manage.py sqlflush перед выполнением, чтобы избежать стирания таблиц, которые вы можете оставить без изменений.

Кроме того, согласно текущим Django docs, в Django 1.5 новый параметр ./manage.py flush --no-initial-data будет reset данных и не загружать исходные данные.

Ответ 2

Для Django <= 1.4 вы можете использовать команду управления reset.

./manage.py sqlreset myapp1 myapp2