Opened 9 years ago

Closed 9 years ago

#16088 closed Bug (needsinfo)

Multi-database tests fail in ContentType

Reported by: def@… Owned by: nobody
Component: Database layer (models, ORM) Version: 1.2
Severity: Normal Keywords: ContentType
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Łukasz Rekucki)

I have a multi-database setup:

    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'wall2',
        'HOST': 'localhost',
        'PORT': '',

    'slave': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'wall2',
        'HOST': 'localhost',
        'PORT': '',
        'TEST_MIRROR': 'default',

    'station': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'station',
        'HOST': 'localhost',
        'PORT': '',
        'TEST_DEPENDENCIES': ['default',]

    'catalog': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'catalog',
        'HOST': 'localhost',
        'PORT': '',
        'TEST_DEPENDENCIES': ['default', 'station']

I have 2 routers, one handles the master/slave and one handles the 2 "data" database station and catalog. they run fine on production, but when we try to run our unit tests i get the following stack trace:

Traceback (most recent call last):
  File "./", line 11, in <module>
  File "/usr/lib/python2.7/site-packages/django/core/management/", line 438, in execute_manager
  File "/usr/lib/python2.7/site-packages/django/core/management/", line 379, in execute
  File "/usr/lib/python2.7/site-packages/django/core/management/", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/lib/python2.7/site-packages/django/core/management/", line 220, in execute
    output = self.handle(*args, **options)
  File "/usr/lib/python2.7/site-packages/south/management/commands/", line 8, in handle
    super(Command, self).handle(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/django/core/management/commands/", line 37, in handle
    failures = test_runner.run_tests(test_labels)
  File "/usr/lib/python2.7/site-packages/django/test/", line 396, in run_tests
    old_config = self.setup_databases()
  File "/usr/lib/python2.7/site-packages/django/test/", line 334, in setup_databases
    test_db_name = connection.creation.create_test_db(self.verbosity, autoclobber=not self.interactive)
  File "/usr/lib/python2.7/site-packages/django/db/backends/", line 357, in create_test_db
  File "/usr/lib/python2.7/site-packages/django/core/management/", line 166, in call_command
    return klass.execute(*args, **defaults)
  File "/usr/lib/python2.7/site-packages/django/core/management/", line 220, in execute
    output = self.handle(*args, **options)
  File "/usr/lib/python2.7/site-packages/django/core/management/", line 351, in handle
    return self.handle_noargs(**options)
  File "/usr/lib/python2.7/site-packages/django/core/management/commands/", line 107, in handle_noargs
    emit_post_sync_signal(created_models, verbosity, interactive, db)
  File "/usr/lib/python2.7/site-packages/django/core/management/", line 182, in emit_post_sync_signal
    interactive=interactive, db=db)
  File "/usr/lib/python2.7/site-packages/django/dispatch/", line 172, in send
    response = receiver(signal=self, sender=sender, **named)
  File "/usr/lib/python2.7/site-packages/django/contrib/contenttypes/", line 25, in update_contenttypes
  File "/usr/lib/python2.7/site-packages/django/db/models/", line 458, in save
    self.save_base(using=using, force_insert=force_insert, force_update=force_update)
  File "/usr/lib/python2.7/site-packages/django/db/models/", line 551, in save_base
    result = manager._insert(values, return_id=update_pk, using=using)
  File "/usr/lib/python2.7/site-packages/django/db/models/", line 195, in _insert
    return insert_query(self.model, values, **kwargs)
  File "/usr/lib/python2.7/site-packages/django/db/models/", line 1524, in insert_query
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/usr/lib/python2.7/site-packages/django/db/models/sql/", line 788, in execute_sql
    cursor = super(SQLInsertCompiler, self).execute_sql(None)
  File "/usr/lib/python2.7/site-packages/django/db/models/sql/", line 732, in execute_sql
    cursor.execute(sql, params)
  File "/usr/lib/python2.7/site-packages/django/db/backends/mysql/", line 86, in execute
    return self.cursor.execute(query, args)
  File "/usr/lib64/python2.7/site-packages/MySQLdb/", line 174, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib64/python2.7/site-packages/MySQLdb/", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
django.db.utils.IntegrityError: (1062, "Duplicate entry 'tools-station' for key 'app_label'")

after some debugging i've found that the

    def update_contenttypes(app, created_models, verbosity=2, **kwargs):

method looks up the tools-station content type in the station database, doesn't find it, and then tries to write it to the default database, where it already exists.

by simply adding "using('default')" to the two ContentType.objects calls in the above method everything works fine. i'm not sure if all content types are meant to be in the 'default' database, but that seems to be the only way it can work at this point?

i'll attach a simple patch,

Attachments (3)

management.diff (392 bytes) - added by anonymous 9 years ago. (1.6 KB) - added by def@… 9 years ago.
db router (699 bytes) - added by def@… 9 years ago.
last router in chain

Download all attachments as: .zip

Change History (12)

Changed 9 years ago by anonymous

Attachment: management.diff added

comment:1 Changed 9 years ago by Aymeric Augustin

Resolution: needsinfo
Status: newclosed

Either your database routers allow reading ContentType objects in the 'station' database (which they shouldn't), or they are bypassed somehow.

Could you post the code of your routers?

comment:2 Changed 9 years ago by Aymeric Augustin

And, obviously, re-open the ticket - thanks :)

Changed 9 years ago by def@…

Attachment: added

db router

comment:3 Changed 9 years ago by anonymous

Resolution: needsinfo
Status: closedreopened

Changed 9 years ago by def@…

Attachment: added

last router in chain

comment:4 Changed 9 years ago by def@…

UI/UX: unset

i have added a test for ContentType and the first router returns 'None' and the final router returns slave on calls to db_for_read for ContentType.

comment:5 Changed 9 years ago by Bas Peschier

Seems like this is not the only ticket about multi-db contenttype problems, could you test whether ticket #16281 solves your problem?

comment:6 Changed 9 years ago by Łukasz Rekucki

Description: modified (diff)

Fixed formatting (please use preview!).

comment:7 Changed 9 years ago by Aymeric Augustin

I tried and failed to reproduce this bug. We'll need the original reporter's feedback to determine if it's a duplicate of #16281.

While investigating, I stumbled upon another problem and I created #16353.

comment:8 Changed 9 years ago by anonymous

well, i'm testing with 1.2.5, so i had to edit the patch as follows, but it didnt' work for me:

        #return self.model_class()._default_manager.using(self._state.db).get(**kwargs)
        return self.model_class()._default_manager.using(self.model_class().objects.db).get(**kwargs)

but still got the same error:

django.db.utils.IntegrityError: (1062, "Duplicate entry 'tools-station' for key 'app_label'")

comment:9 Changed 9 years ago by Aymeric Augustin

Resolution: needsinfo
Status: reopenedclosed

If someone can provide a way to reproduce this on 1.3, please reopen the ticket.

Only critical fixes are backported to the 1.2 branch, and this problem is certainly not critical.

Note: See TracTickets for help on using tickets.
Back to Top