Opened 12 years ago

Closed 10 years ago

#12767 closed Bug (duplicate)

Problem running syncdb with a multi-db router that restricts auth to a single database

Reported by: Russell Keith-Magee Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: klemens@…, kmpm@…, jonj@…, digitalxero@…, mmitar@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no


Via Klemens Mantzos on django-users:

If i do

python syncdb --database=default

before i sync the users database this error comes up (which seems ok to me):

django.db.utils.DatabaseError: (1146, "Table 'multidb_user.auth_permission' doesn't exist")

but if i do this:

python syncdb --database=users

i get that every time (no matter if django_content_type already exists in the default db or not):

django.db.utils.DatabaseError: (1146, "Table 'multidb_user.django_content_type' doesn't exist")

Router config

# don't know but OtherRouter is maybe obsolete.
DATABASE_ROUTERS = ['dbrouter.AuthRouter', 'dbrouter.OtherRouter']


class AuthRouter(object):
  """A router to control all database operations on models in
  the contrib.auth application"""


  def allow_syncdb(self, db, model):
      "Make sure the auth app only appears on the 'credentials' db"
      if db == 'users':
          return model._meta.app_label == 'auth'
      elif model._meta.app_label == 'auth':
          return False
      return None

class OtherRouter(object):
  """A router that sets up a simple master/slave configuration"""


  def allow_syncdb(self, db, model):
      "Explicitly put all models on all databases."
      return True

Attachments (1)

block_contenttypes.diff (860 bytes) - added by Adam Vandenberg 12 years ago.
Hack: blocks command if ContentType isn't allowed to sync into the target db.

Download all attachments as: .zip

Change History (19)

comment:1 Changed 12 years ago by Russell Keith-Magee

Triage Stage: UnreviewedAccepted
Version: 1.2-alphaSVN

The issue appears to be the way that the contenttype post-syncdb handler deals with a multi-db situation.

comment:2 Changed 12 years ago by fetzig

Cc: klemens@… added

comment:3 Changed 12 years ago by kmpm

Cc: kmpm@… added

comment:4 Changed 12 years ago by jonj

Cc: jonj@… added

Changed 12 years ago by Adam Vandenberg

Attachment: block_contenttypes.diff added

Hack: blocks command if ContentType isn't allowed to sync into the target db.

comment:5 Changed 12 years ago by Russell Keith-Magee

After closer inspection, I'm going to mark this someday/maybe.

The underlying problem here is that auth has foreign keys to contenttypes. This means that you need to deal with referential integrity across databases, which is a non-trivial problem to solve (other than the obvious workaround of putting contenttypes on the same database as auth)

An alternative solution would be to modify the contenttypes syncdb handler so that contenttypes can be synchronized onto multiple databases. However, this would require lots of extra logic to ensure that databases remained in sync, including ensuring that primary key allocation for content types is consistent between databases.

However, I will make a change to the multi-db docs -- they currently suggest that routers can be used to put auth onto a separate database, and while this is technically true, it won't be true for many uses in practice. Better to avoid the implication altogether.

comment:6 Changed 12 years ago by Russell Keith-Magee

(In [12751]) Refs #12767 -- Modified the multi-db docs to remove the implication that contrib.auth can be easily put on a separate database.

comment:7 Changed 12 years ago by Russell Keith-Magee

milestone: 1.2
Triage Stage: AcceptedSomeday/Maybe

comment:8 Changed 12 years ago by fetzig

maybe its a stupid question but I just don't get it, and need to ask:

@russellm does that mean that its required to keep models with foreign keys to each other together in one db (even with configured router)?

or is it just a "special" problem with the syncdb of contenttypes?

thx for your time russel.


comment:9 Changed 12 years ago by Russell Keith-Magee

@fetzig -- This is not specific to ContentTypes. Foreign Keys can't cross databases. This is all a consequence of referential integrity -- a database can't guarantee referential integrity if it doesn't have access to the ground truth. There might be ways to relax this restriction, but it isn't trivial.

comment:10 Changed 12 years ago by Digitalxero

Cc: digitalxero@… added
Has patch: set
milestone: 1.2

This bug affects any multi-db config that has django.contrib.contenttpes installed even if the models being synced do not have a ForeignKey to ContentType

My examples, I have a DB of gis data for zip codes, counties / states etc. This DB is used by a number of sites so I want it in it's own DB, and nothing else gets synced there but when I do syncdb --database=gis

I get

django.db.utils.DatabaseError: (1146, "Table 'gis.django_content_type' doesn't exist")

None of the models in my gis app have relations to ContentTypes and no app in the rest of the site has relations to the gis app, this is something I ensure with a DB Router. So this error is coming because the ContentTypes app wants to track all installed applications, but it should not be tracking items it can have no relation with.

This patch does fix the error

comment:11 Changed 12 years ago by Russell Keith-Magee

milestone: 1.2
Patch needs improvement: set

The patch doesn't fix the error at all; it hides it. It means that you won't have a content type for the objects in the separate database, which has the potential to cause all sorts of other problems.

I also have a suspicion there might be something wrong with your router; If you're getting errors about "gis.django_content_type", that suggests that something in your routing configuration is pushing contenttype to the gis database, which shouldn't be happening.

comment:12 Changed 12 years ago by Digitalxero

I am fairly sure it is because the update_contenttypes method sets using(db) for all db calls (eg

comment:13 Changed 12 years ago by Russell Keith-Magee

You may want to update to trunk. The [source:/django/trunk/django/contrib/contenttypes/ current source code] doesn't force the database at all. There aren't any calls to using() or save(using=)

comment:14 Changed 12 years ago by Digitalxero

Thats what I get for testing with beta1 and not upgrading to trunk when I find a bug. Just upgraded to trunk and verified I no longer see my issue even without this patch.

comment:15 Changed 12 years ago by Marco Paolini

maybe related to #14662

comment:16 Changed 11 years ago by Julien Phalip

Severity: Normal
Type: Bug

comment:17 Changed 10 years ago by Mitar

Cc: mmitar@… added
Easy pickings: unset
UI/UX: unset

comment:18 Changed 10 years ago by Aymeric Augustin

Resolution: duplicate
Status: newclosed
Triage Stage: Someday/MaybeAccepted

This is a duplicate of #16039 that's fixed in 1.5.

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