django_content_type_app_label_key Constraint on Heroku


Django comes with some awesome CLI tools. Manage.py is a beast of magic and lore. And it loves the fantastical kingdom of Heroku, where is romps with merry measure twixt the ether. But, when I've tried to go through a dumpdata of a previous site, syncdb on a migration to Heroku, and loaddata for moving the data, I've run into a snag on django_content_type_app_label_key more than once. Here are some resolutions.

The Error Stack

Specifically, when I do a sync of the database:

heroku run python manage.py syncdb

It works like a charm. And then a loading of the data:

heroku run python manage.py loaddata data.json

It runs for a bit then spews this small hiccup:

Running python manage.py loaddata data.json attached to terminal... up, run.2
Problem installing fixture 'data.json': Traceback (most recent call last):
  File "/app/lib/python2.7/site-packages/django/core/management/commands/loaddata.py", line 174, in handle
    obj.save(using=using)
  # ...more stack trace...
  File "/app/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 44, in execute
    return self.cursor.execute(query, args)
IntegrityError: duplicate key value violates unique constraint "django_content_type_app_label_key"

Lovely.

It turns out that syncdb, in addition to running the DDLs for your table creation also populates the django_content_type table. And then when you loaddata it tries to repopulate the table, violating the unique constraint on the content type name.

Make the Magic Live Again

There are a couple ways around this:

Dump Something Specific

When you dumpdata, only dump specific apps instead of the whole project. For example:

python manage.py dumpdata myApp

Django 1.3 Exclude

If you're on Django 1.3 or above, you get a nice new option with dumpdata to exclude certain apps. So you could run:

python manage.py dumpdata --exclude contenttypes

Try in Vain to Reset

Another one I tried (but didn't work) was:

heroku run python aprilandjake/manage.py reset contenttypes

Sql Truncate

Or, if you're still trying to dumpdata on your whole project, you could syncdb on Heroku and then truncate the data out of django_content_type like this:

heroku run python aprilandjake/manage.py dbshell

And then truncate (inside the dbshell):

truncate django_content_type cascade;

Problem for me is that didn't work either. I am on the super cheap in Heroku, so I get this lovely denial:

Running python manage.py dbshell attached to terminal... up, run.5
Error: You appear not to have the 'psql' program installed or on your path.

(It's not available in a shared database):

heroku pg:psql
!  Cannot ingress to a shared database

Delete via Admin UI

And finally, if you want to get rid of the data via the admin UI, set it up to appear as editable. In an admin.py in your project, try something like this:

from django.contrib.contenttypes.models import ContentType
    
class ContentTypeAdmin(admin.ModelAdmin):
  list_display = ['name', 'app_label']
  fieldsets = (
    ('', {
      'classes': ('',),
      'fields': ('name', 'app_label')
    }),
  )

  admin.site.register(ContentType, ContentTypeAdmin)

Now you should be able to loaddata and feel the Django wind in your hair and the Heroku grass beneath your feet again.