Reputation: 6640
I'm trying to sync data between two django installations (production and testing). I'm doing this using ./manage.py dumpdata --natural
on production, then ./manage.py loaddata
into a freshly syncdb
'ed database on testing.
Everything was working fine until I added a new custom permission. The production syncdb
loaded this new permission in a different order (with different primary key) than a new syncdb
on an empty database does. Consequently, it gets a different ID. So despite using natural keys, when I attempt to load the data, I'm getting this error when the first out-of-order permission object is loaded:
IntegrityError: duplicate key value violates unique constraint "auth_permission_content_type_id_codename_key"
The easiest way I can think of to fix this is to remove all data from every table in the testing installation -- that is, to use syncdb
just to create tables, and not to also load initial data. But syncdb
doesn't let you skip the initial data/signals step. Short of enumerating every model or table name explicitly, how can I remove all initial data after calling syncdb
? Or is there a way to create just the empty tables without using syncdb
?
./manage.py flush
isn't what I'm after -- it reloads initial data and triggers syncdb signals.
Upvotes: 10
Views: 9387
Reputation: 308779
For Django <= 1.4, you can use the reset
management command.
./manage.py sqlreset myapp1 myapp2
Upvotes: 0
Reputation: 8251
According to the help for flush command (I'm using Django 1.3.1) the SQL that is executed is the same SQL obtained from ./manage.py sqlflush
, and then the initial data fixtures is reinstalled.
$ python manage.py help flush
Usage: manage.py flush [options]
Executes ``sqlflush`` on the current database.
To get the same data wiping capabilities minus the fixture loading you can obtain the SQL by calling ./manage.py sqlflush
and then execute that SQL using Django's built-in support for executing arbitrary 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()
This has the added benefit that you can modify the SQL from ./manage.py sqlflush
before execution to avoid wiping tables that you might want to leave intact.
Also, according to the current Django docs, in Django 1.5 a new parameter ./manage.py flush --no-initial-data
will reset the data and not load the initial data fixture.
Upvotes: 9