No migrations to apply but Django is still trying to create a new content type
Question: I pushed a new release to a server last week which included a database
migration for a new table. This completed as expected, and works, but now on
every deployment when the server runs it's migrations I'm seeing no migrations
to apply, but also a unique key error on content types;

    
    
    Running migrations:
    No migrations to apply.
    ...
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
    django.db.utils.IntegrityError
    (1062, "Duplicate entry 'djangocms_newsletter-signup' for key 'django_content_type_app_label_45f3b1d93ec8c61c_uniq'")
    

The table is in the database, the content type for the `Signup` model is in
the content types table, the migration is in the migrations table... so why
does Django try to create a new content type still?

Migrations are ran as part of a straightforward post deployment script that I
use for all projects;

    
    
    #!/bin/bash
    
    set -e
    
    PROJ_PATH=/var/www/django/myproj
    
    cd $PROJ_PATH
    
    echo 'clear-out...'
    find $PROJ_PATH -name "*.pyc" -exec rm -rf '{}' ';'
    find $PROJ_PATH -name "*.pyo" -exec rm -rf '{}' ';'
    
    echo 'set DJANGO_SETTINGS_MODULE'
    export DJANGO_SETTINGS_MODULE="project.settings.local_override"
    
    echo 'activating...'
    source ../bin/activate
    
    echo 'pip install...'
    pip install -r requirements.txt --no-deps
    
    echo 'migrate...'
    python manage.py migrate --noinput
    
    echo 'collectstatic...'
    python manage.py collectstatic --noinput
    
    echo 'restart apache...'
    sudo service apache2 restart
    
    deactivate
    

At the moment, I've been clearing the app name from the existing content type
in order to allow the deployment to succeed, but now I just want to understand
what the issue is so that I can resolve it in future.

Full Traceback;

    
    
    Traceback (most recent call last):
    File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 165, in handle
    emit_post_migrate_signal(created_models, self.verbosity, self.interactive, connection.alias)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/core/management/sql.py", line 268, in emit_post_migrate_signal
    using=db)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 198, in send
    response = receiver(signal=self, sender=sender, **named)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/contrib/contenttypes/management.py", line 56, in update_contenttypes
    ContentType.objects.using(using).bulk_create(cts)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/models/query.py", line 409, in bulk_create
    self._batched_insert(objs_without_pk, fields, batch_size)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/models/query.py", line 938, in _batched_insert
    using=self.db)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/models/manager.py", line 92, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/models/query.py", line 921, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 921, in execute_sql
    cursor.execute(sql, params)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 129, in execute
    return self.cursor.execute(query, args)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
    self.errorhandler(self, exc, value)
    File "/var/www/django/myproj/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
    django.db.utils.
    IntegrityError: (1062, "Duplicate entry 'djangocms_newsletter-signup' for key 'django_content_type_app_label_45f3b1d93ec8c61c_uniq'")
    execute bash /var/www/django/myproj/myproj/shell_scripts/production_post_deployment.sh
    


Answer: After coming across this issue again I've debugged it using the shell on the
server as it's not been possible to reproduce & found that the issue is caused
by cached ContentType objects.

Let me illustrate;

    
    
    >>> content_types = dict((ct.model, ct) for ct in ContentType.objects.filter(app_label='consoles'))
    >>> content_types
    {}
    >>> content_types = dict((ct.model, ct) for ct in ContentType.objects.filter(app_label='news'))
    >>> content_types
    {u'latestnews': <ContentType: latest news>}
    >>> from django.core.cache import cache
    >>> cache.clear()
    >>> content_types = dict((ct.model, ct) for ct in ContentType.objects.filter(app_label='consoles'))
    >>> content_types
    {u'runner': <ContentType: runner>, u'importedclient': <ContentType: imported client>, u'placetype': <ContentType: place type>, u'invoice': <ContentType: invoice>, u'placetypetotal': <ContentType: place type total>, u'clientconsoles': <ContentType: client consoles>, u'emailtemplate': <ContentType: email template>, u'event': <ContentType: event>, u'occupation': <ContentType: occupation>, u'console': <ContentType: console>, u'meettheexperts': <ContentType: meet the experts>, u'auditlog': <ContentType: audit log entry>, u'proxyuser': <ContentType: user>, u'consoleuser': <ContentType: Console User>, u'paidby': <ContentType: paid by>, u'meettheexpertstransaction': <ContentType: Meet the experts Transaction>, u'clientuserconsole': <ContentType: client user console>, u'paymentmethod': <ContentType: payment method>, u'transaction': <ContentType: transaction>, u'country': <ContentType: Country>, u'client': <ContentType: client>, u'place': <ContentType: place>, u'consoletotal': <ContentType: console total>}
    

So a fix to the cached manager which was caching all content types has
resolved the issue.

