parts/django/docs/topics/db/multi-db.txt
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 ==================
       
     2 Multiple databases
       
     3 ==================
       
     4 
       
     5 .. versionadded:: 1.2
       
     6 
       
     7 This topic guide describes Django's support for interacting with
       
     8 multiple databases. Most of the rest of Django's documentation assumes
       
     9 you are interacting with a single database. If you want to interact
       
    10 with multiple databases, you'll need to take some additional steps.
       
    11 
       
    12 Defining your databases
       
    13 =======================
       
    14 
       
    15 The first step to using more than one database with Django is to tell
       
    16 Django about the database servers you'll be using. This is done using
       
    17 the :setting:`DATABASES` setting. This setting maps database aliases,
       
    18 which are a way to refer to a specific database throughout Django, to
       
    19 a dictionary of settings for that specific connection. The settings in
       
    20 the inner dictionaries are described fully in the :setting:`DATABASES`
       
    21 documentation.
       
    22 
       
    23 Databases can have any alias you choose. However, the alias
       
    24 ``default`` has special significance. Django uses the database with
       
    25 the alias of ``default`` when no other database has been selected. If
       
    26 you don't have a ``default`` database, you need to be careful to
       
    27 always specify the database that you want to use.
       
    28 
       
    29 The following is an example ``settings.py`` snippet defining two
       
    30 databases -- a default PostgreSQL database and a MySQL database called
       
    31 ``users``:
       
    32 
       
    33 .. code-block:: python
       
    34 
       
    35     DATABASES = {
       
    36         'default': {
       
    37             'NAME': 'app_data',
       
    38             'ENGINE': 'django.db.backends.postgresql_psycopg2',
       
    39             'USER': 'postgres_user',
       
    40             'PASSWORD': 's3krit'
       
    41         },
       
    42         'users': {
       
    43             'NAME': 'user_data',
       
    44             'ENGINE': 'django.db.backends.mysql',
       
    45             'USER': 'mysql_user',
       
    46             'PASSWORD': 'priv4te'
       
    47         }
       
    48     }
       
    49 
       
    50 If you attempt to access a database that you haven't defined in your
       
    51 :setting:`DATABASES` setting, Django will raise a
       
    52 ``django.db.utils.ConnectionDoesNotExist`` exception.
       
    53 
       
    54 Synchronizing your databases
       
    55 ============================
       
    56 
       
    57 The :djadmin:`syncdb` management command operates on one database at a
       
    58 time. By default, it operates on the ``default`` database, but by
       
    59 providing a :djadminopt:`--database` argument, you can tell syncdb to
       
    60 synchronize a different database. So, to synchronize all models onto
       
    61 all databases in our example, you would need to call::
       
    62 
       
    63     $ ./manage.py syncdb
       
    64     $ ./manage.py syncdb --database=users
       
    65 
       
    66 If you don't want every application to be synchronized onto a
       
    67 particular database, you can define a :ref:`database
       
    68 router<topics-db-multi-db-routing>` that implements a policy
       
    69 constraining the availability of particular models.
       
    70 
       
    71 Alternatively, if you want fine-grained control of synchronization,
       
    72 you can pipe all or part of the output of :djadmin:`sqlall` for a
       
    73 particular application directly into your database prompt, like this::
       
    74 
       
    75     $ ./manage.py sqlall sales | ./manage.py dbshell
       
    76 
       
    77 Using other management commands
       
    78 -------------------------------
       
    79 
       
    80 The other ``django-admin.py`` commands that interact with the database
       
    81 operate in the same way as :djadmin:`syncdb` -- they only ever operate
       
    82 on one database at a time, using :djadminopt:`--database` to control
       
    83 the database used.
       
    84 
       
    85 .. _topics-db-multi-db-routing:
       
    86 
       
    87 Automatic database routing
       
    88 ==========================
       
    89 
       
    90 The easiest way to use multiple databases is to set up a database
       
    91 routing scheme. The default routing scheme ensures that objects remain
       
    92 'sticky' to their original database (i.e., an object retrieved from
       
    93 the ``foo`` database will be saved on the same database). The default
       
    94 routing scheme ensures that if a database isn't specified, all queries
       
    95 fall back to the ``default`` database.
       
    96 
       
    97 You don't have to do anything to activate the default routing scheme
       
    98 -- it is provided 'out of the box' on every Django project. However,
       
    99 if you want to implement more interesting database allocation
       
   100 behaviors, you can define and install your own database routers.
       
   101 
       
   102 Database routers
       
   103 ----------------
       
   104 
       
   105 A database Router is a class that provides up to four methods:
       
   106 
       
   107 .. method:: db_for_read(model, **hints)
       
   108 
       
   109     Suggest the database that should be used for read operations for
       
   110     objects of type ``model``.
       
   111 
       
   112     If a database operation is able to provide any additional
       
   113     information that might assist in selecting a database, it will be
       
   114     provided in the ``hints`` dictionary. Details on valid hints are
       
   115     provided :ref:`below <topics-db-multi-db-hints>`.
       
   116 
       
   117     Returns None if there is no suggestion.
       
   118 
       
   119 .. method:: db_for_write(model, **hints)
       
   120 
       
   121     Suggest the database that should be used for writes of objects of
       
   122     type Model.
       
   123 
       
   124     If a database operation is able to provide any additional
       
   125     information that might assist in selecting a database, it will be
       
   126     provided in the ``hints`` dictionary. Details on valid hints are
       
   127     provided :ref:`below <topics-db-multi-db-hints>`.
       
   128 
       
   129     Returns None if there is no suggestion.
       
   130 
       
   131 .. method:: allow_relation(obj1, obj2, **hints)
       
   132 
       
   133     Return True if a relation between obj1 and obj2 should be
       
   134     allowed, False if the relation should be prevented, or None if
       
   135     the router has no opinion. This is purely a validation operation,
       
   136     used by foreign key and many to many operations to determine if a
       
   137     relation should be allowed between two objects.
       
   138 
       
   139 .. method:: allow_syncdb(db, model)
       
   140 
       
   141     Determine if the ``model`` should be synchronized onto the
       
   142     database with alias ``db``. Return True if the model should be
       
   143     synchronized, False if it should not be synchronized, or None if
       
   144     the router has no opinion. This method can be used to determine
       
   145     the availability of a model on a given database.
       
   146 
       
   147 A router doesn't have to provide *all* these methods - it omit one or
       
   148 more of them. If one of the methods is omitted, Django will skip that
       
   149 router when performing the relevant check.
       
   150 
       
   151 .. _topics-db-multi-db-hints:
       
   152 
       
   153 Hints
       
   154 ~~~~~
       
   155 
       
   156 The hints received by the database router can be used to decide which
       
   157 database should receive a given request.
       
   158 
       
   159 At present, the only hint that will be provided is ``instance``, an
       
   160 object instance that is related to the read or write operation that is
       
   161 underway. This might be the instance that is being saved, or it might
       
   162 be an instance that is being added in a many-to-many relation. In some
       
   163 cases, no instance hint will be provided at all. The router checks for
       
   164 the existence of an instance hint, and determine if that hint should be
       
   165 used to alter routing behavior.
       
   166 
       
   167 Using routers
       
   168 -------------
       
   169 
       
   170 Database routers are installed using the :setting:`DATABASE_ROUTERS`
       
   171 setting. This setting defines a list of class names, each specifying a
       
   172 router that should be used by the master router
       
   173 (``django.db.router``).
       
   174 
       
   175 The master router is used by Django's database operations to allocate
       
   176 database usage. Whenever a query needs to know which database to use,
       
   177 it calls the master router, providing a model and a hint (if
       
   178 available). Django then tries each router in turn until a database
       
   179 suggestion can be found. If no suggestion can be found, it tries the
       
   180 current ``_state.db`` of the hint instance. If a hint instance wasn't
       
   181 provided, or the instance doesn't currently have database state, the
       
   182 master router will allocate the ``default`` database.
       
   183 
       
   184 An example
       
   185 ----------
       
   186 
       
   187 .. admonition:: Example purposes only!
       
   188 
       
   189     This example is intended as a demonstration of how the router
       
   190     infrastructure can be used to alter database usage. It
       
   191     intentionally ignores some complex issues in order to
       
   192     demonstrate how routers are used.
       
   193 
       
   194     This example won't work if any of the models in ``myapp`` contain
       
   195     relationships to models outside of the ``other`` database.
       
   196     :ref:`Cross-database relationships <no_cross_database_relations>`
       
   197     introduce referential integrity problems that Django can't
       
   198     currently handle.
       
   199 
       
   200     The master/slave configuration described is also flawed -- it
       
   201     doesn't provide any solution for handling replication lag (i.e.,
       
   202     query inconsistencies introduced because of the time taken for a
       
   203     write to propagate to the slaves). It also doesn't consider the
       
   204     interaction of transactions with the database utilization strategy.
       
   205 
       
   206 So - what does this mean in practice? Say you want ``myapp`` to
       
   207 exist on the ``other`` database, and you want all other models in a
       
   208 master/slave relationship between the databases ``master``, ``slave1`` and
       
   209 ``slave2``. To implement this, you would need 2 routers::
       
   210 
       
   211     class MyAppRouter(object):
       
   212         """A router to control all database operations on models in
       
   213         the myapp application"""
       
   214 
       
   215         def db_for_read(self, model, **hints):
       
   216             "Point all operations on myapp models to 'other'"
       
   217             if model._meta.app_label == 'myapp':
       
   218                 return 'other'
       
   219             return None
       
   220 
       
   221         def db_for_write(self, model, **hints):
       
   222             "Point all operations on myapp models to 'other'"
       
   223             if model._meta.app_label == 'myapp':
       
   224                 return 'other'
       
   225             return None
       
   226 
       
   227         def allow_relation(self, obj1, obj2, **hints):
       
   228             "Allow any relation if a model in myapp is involved"
       
   229             if obj1._meta.app_label == 'myapp' or obj2._meta.app_label == 'myapp':
       
   230                 return True
       
   231             return None
       
   232 
       
   233         def allow_syncdb(self, db, model):
       
   234             "Make sure the myapp app only appears on the 'other' db"
       
   235             if db == 'other':
       
   236                 return model._meta.app_label == 'myapp'
       
   237             elif model._meta.app_label == 'myapp':
       
   238                 return False
       
   239             return None
       
   240 
       
   241     class MasterSlaveRouter(object):
       
   242         """A router that sets up a simple master/slave configuration"""
       
   243 
       
   244         def db_for_read(self, model, **hints):
       
   245             "Point all read operations to a random slave"
       
   246             return random.choice(['slave1','slave2'])
       
   247 
       
   248         def db_for_write(self, model, **hints):
       
   249             "Point all write operations to the master"
       
   250             return 'master'
       
   251 
       
   252         def allow_relation(self, obj1, obj2, **hints):
       
   253             "Allow any relation between two objects in the db pool"
       
   254             db_list = ('master','slave1','slave2')
       
   255             if obj1._state.db in db_list and obj2._state.db in db_list:
       
   256                 return True
       
   257             return None
       
   258 
       
   259         def allow_syncdb(self, db, model):
       
   260             "Explicitly put all models on all databases."
       
   261             return True
       
   262 
       
   263 Then, in your settings file, add the following (substituting ``path.to.`` with
       
   264 the actual python path to the module where you define the routers)::
       
   265 
       
   266     DATABASE_ROUTERS = ['path.to.MyAppRouter', 'path.to.MasterSlaveRouter']
       
   267 
       
   268 The order in which routers are processed is significant. Routers will
       
   269 be queried in the order the are listed in the
       
   270 :setting:`DATABASE_ROUTERS` setting . In this example, the
       
   271 ``MyAppRouter`` is processed before the ``MasterSlaveRouter``, and as a
       
   272 result, decisions concerning the models in ``myapp`` are processed
       
   273 before any other decision is made. If the :setting:`DATABASE_ROUTERS`
       
   274 setting listed the two routers in the other order,
       
   275 ``MasterSlaveRouter.allow_syncdb()`` would be processed first. The
       
   276 catch-all nature of the MasterSlaveRouter implementation would mean
       
   277 that all models would be available on all databases.
       
   278 
       
   279 With this setup installed, lets run some Django code::
       
   280 
       
   281     >>> # This retrieval will be performed on the 'credentials' database
       
   282     >>> fred = User.objects.get(username='fred')
       
   283     >>> fred.first_name = 'Frederick'
       
   284 
       
   285     >>> # This save will also be directed to 'credentials'
       
   286     >>> fred.save()
       
   287 
       
   288     >>> # These retrieval will be randomly allocated to a slave database
       
   289     >>> dna = Person.objects.get(name='Douglas Adams')
       
   290 
       
   291     >>> # A new object has no database allocation when created
       
   292     >>> mh = Book(title='Mostly Harmless')
       
   293 
       
   294     >>> # This assignment will consult the router, and set mh onto
       
   295     >>> # the same database as the author object
       
   296     >>> mh.author = dna
       
   297 
       
   298     >>> # This save will force the 'mh' instance onto the master database...
       
   299     >>> mh.save()
       
   300 
       
   301     >>> # ... but if we re-retrieve the object, it will come back on a slave
       
   302     >>> mh = Book.objects.get(title='Mostly Harmless')
       
   303 
       
   304 
       
   305 Manually selecting a database
       
   306 =============================
       
   307 
       
   308 Django also provides an API that allows you to maintain complete control
       
   309 over database usage in your code. A manually specified database allocation
       
   310 will take priority over a database allocated by a router.
       
   311 
       
   312 Manually selecting a database for a ``QuerySet``
       
   313 ------------------------------------------------
       
   314 
       
   315 You can select the database for a ``QuerySet`` at any point in the
       
   316 ``QuerySet`` "chain." Just call ``using()`` on the ``QuerySet`` to get
       
   317 another ``QuerySet`` that uses the specified database.
       
   318 
       
   319 ``using()`` takes a single argument: the alias of the database on
       
   320 which you want to run the query. For example::
       
   321 
       
   322     >>> # This will run on the 'default' database.
       
   323     >>> Author.objects.all()
       
   324 
       
   325     >>> # So will this.
       
   326     >>> Author.objects.using('default').all()
       
   327 
       
   328     >>> # This will run on the 'other' database.
       
   329     >>> Author.objects.using('other').all()
       
   330 
       
   331 Selecting a database for ``save()``
       
   332 -----------------------------------
       
   333 
       
   334 Use the ``using`` keyword to ``Model.save()`` to specify to which
       
   335 database the data should be saved.
       
   336 
       
   337 For example, to save an object to the ``legacy_users`` database, you'd
       
   338 use this::
       
   339 
       
   340     >>> my_object.save(using='legacy_users')
       
   341 
       
   342 If you don't specify ``using``, the ``save()`` method will save into
       
   343 the default database allocated by the routers.
       
   344 
       
   345 Moving an object from one database to another
       
   346 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       
   347 
       
   348 If you've saved an instance to one database, it might be tempting to
       
   349 use ``save(using=...)`` as a way to migrate the instance to a new
       
   350 database. However, if you don't take appropriate steps, this could
       
   351 have some unexpected consequences.
       
   352 
       
   353 Consider the following example::
       
   354 
       
   355     >>> p = Person(name='Fred')
       
   356     >>> p.save(using='first')  # (statement 1)
       
   357     >>> p.save(using='second') # (statement 2)
       
   358 
       
   359 In statement 1, a new ``Person`` object is saved to the ``first``
       
   360 database. At this time, ``p`` doesn't have a primary key, so Django
       
   361 issues a SQL ``INSERT`` statement. This creates a primary key, and
       
   362 Django assigns that primary key to ``p``.
       
   363 
       
   364 When the save occurs in statement 2, ``p`` already has a primary key
       
   365 value, and Django will attempt to use that primary key on the new
       
   366 database. If the primary key value isn't in use in the ``second``
       
   367 database, then you won't have any problems -- the object will be
       
   368 copied to the new database.
       
   369 
       
   370 However, if the primary key of ``p`` is already in use on the
       
   371 ``second`` database, the existing object in the ``second`` database
       
   372 will be overridden when ``p`` is saved.
       
   373 
       
   374 You can avoid this in two ways. First, you can clear the primary key
       
   375 of the instance. If an object has no primary key, Django will treat it
       
   376 as a new object, avoiding any loss of data on the ``second``
       
   377 database::
       
   378 
       
   379     >>> p = Person(name='Fred')
       
   380     >>> p.save(using='first')
       
   381     >>> p.pk = None # Clear the primary key.
       
   382     >>> p.save(using='second') # Write a completely new object.
       
   383 
       
   384 The second option is to use the ``force_insert`` option to ``save()``
       
   385 to ensure that Django does a SQL ``INSERT``::
       
   386 
       
   387     >>> p = Person(name='Fred')
       
   388     >>> p.save(using='first')
       
   389     >>> p.save(using='second', force_insert=True)
       
   390 
       
   391 This will ensure that the person named ``Fred`` will have the same
       
   392 primary key on both databases. If that primary key is already in use
       
   393 when you try to save onto the ``second`` database, an error will be
       
   394 raised.
       
   395 
       
   396 Selecting a database to delete from
       
   397 -----------------------------------
       
   398 
       
   399 By default, a call to delete an existing object will be executed on
       
   400 the same database that was used to retrieve the object in the first
       
   401 place::
       
   402 
       
   403     >>> u = User.objects.using('legacy_users').get(username='fred')
       
   404     >>> u.delete() # will delete from the `legacy_users` database
       
   405 
       
   406 To specify the database from which a model will be deleted, pass a
       
   407 ``using`` keyword argument to the ``Model.delete()`` method. This
       
   408 argument works just like the ``using`` keyword argument to ``save()``.
       
   409 
       
   410 For example, if you're migrating a user from the ``legacy_users``
       
   411 database to the ``new_users`` database, you might use these commands::
       
   412 
       
   413     >>> user_obj.save(using='new_users')
       
   414     >>> user_obj.delete(using='legacy_users')
       
   415 
       
   416 Using managers with multiple databases
       
   417 --------------------------------------
       
   418 
       
   419 Use the ``db_manager()`` method on managers to give managers access to
       
   420 a non-default database.
       
   421 
       
   422 For example, say you have a custom manager method that touches the
       
   423 database -- ``User.objects.create_user()``. Because ``create_user()``
       
   424 is a manager method, not a ``QuerySet`` method, you can't do
       
   425 ``User.objects.using('new_users').create_user()``. (The
       
   426 ``create_user()`` method is only available on ``User.objects``, the
       
   427 manager, not on ``QuerySet`` objects derived from the manager.) The
       
   428 solution is to use ``db_manager()``, like this::
       
   429 
       
   430     User.objects.db_manager('new_users').create_user(...)
       
   431 
       
   432 ``db_manager()`` returns a copy of the manager bound to the database you specify.
       
   433 
       
   434 Using ``get_query_set()`` with multiple databases
       
   435 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       
   436 
       
   437 If you're overriding ``get_query_set()`` on your manager, be sure to
       
   438 either call the method on the parent (using ``super()``) or do the
       
   439 appropriate handling of the ``_db`` attribute on the manager (a string
       
   440 containing the name of the database to use).
       
   441 
       
   442 For example, if you want to return a custom ``QuerySet`` class from
       
   443 the ``get_query_set`` method, you could do this::
       
   444 
       
   445     class MyManager(models.Manager):
       
   446         def get_query_set(self):
       
   447             qs = CustomQuerySet(self.model)
       
   448             if self._db is not None:
       
   449                 qs = qs.using(self._db)
       
   450             return qs
       
   451 
       
   452 Exposing multiple databases in Django's admin interface
       
   453 =======================================================
       
   454 
       
   455 Django's admin doesn't have any explicit support for multiple
       
   456 databases. If you want to provide an admin interface for a model on a
       
   457 database other than that that specified by your router chain, you'll
       
   458 need to write custom :class:`~django.contrib.admin.ModelAdmin` classes
       
   459 that will direct the admin to use a specific database for content.
       
   460 
       
   461 ``ModelAdmin`` objects have four methods that require customization for
       
   462 multiple-database support::
       
   463 
       
   464     class MultiDBModelAdmin(admin.ModelAdmin):
       
   465         # A handy constant for the name of the alternate database.
       
   466         using = 'other'
       
   467 
       
   468         def save_model(self, request, obj, form, change):
       
   469             # Tell Django to save objects to the 'other' database.
       
   470             obj.save(using=self.using)
       
   471 
       
   472         def queryset(self, request):
       
   473             # Tell Django to look for objects on the 'other' database.
       
   474             return super(MultiDBModelAdmin, self).queryset(request).using(self.using)
       
   475 
       
   476         def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
       
   477             # Tell Django to populate ForeignKey widgets using a query
       
   478             # on the 'other' database.
       
   479             return super(MultiDBModelAdmin, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs)
       
   480 
       
   481         def formfield_for_manytomany(self, db_field, request=None, **kwargs):
       
   482             # Tell Django to populate ManyToMany widgets using a query
       
   483             # on the 'other' database.
       
   484             return super(MultiDBModelAdmin, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)
       
   485 
       
   486 The implementation provided here implements a multi-database strategy
       
   487 where all objects of a given type are stored on a specific database
       
   488 (e.g., all ``User`` objects are in the ``other`` database). If your
       
   489 usage of multiple databases is more complex, your ``ModelAdmin`` will
       
   490 need to reflect that strategy.
       
   491 
       
   492 Inlines can be handled in a similar fashion. They require three customized methods::
       
   493 
       
   494     class MultiDBTabularInline(admin.TabularInline):
       
   495         using = 'other'
       
   496 
       
   497         def queryset(self, request):
       
   498             # Tell Django to look for inline objects on the 'other' database.
       
   499             return super(MultiDBTabularInline, self).queryset(request).using(self.using)
       
   500 
       
   501         def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
       
   502             # Tell Django to populate ForeignKey widgets using a query
       
   503             # on the 'other' database.
       
   504             return super(MultiDBTabularInline, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs)
       
   505 
       
   506         def formfield_for_manytomany(self, db_field, request=None, **kwargs):
       
   507             # Tell Django to populate ManyToMany widgets using a query
       
   508             # on the 'other' database.
       
   509             return super(MultiDBTabularInline, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)
       
   510 
       
   511 Once you've written your model admin definitions, they can be
       
   512 registered with any ``Admin`` instance::
       
   513 
       
   514     from django.contrib import admin
       
   515 
       
   516     # Specialize the multi-db admin objects for use with specific models.
       
   517     class BookInline(MultiDBTabularInline):
       
   518         model = Book
       
   519 
       
   520     class PublisherAdmin(MultiDBModelAdmin):
       
   521         inlines = [BookInline]
       
   522 
       
   523     admin.site.register(Author, MultiDBModelAdmin)
       
   524     admin.site.register(Publisher, PublisherAdmin)
       
   525 
       
   526     othersite = admin.Site('othersite')
       
   527     othersite.register(Publisher, MultiDBModelAdmin)
       
   528 
       
   529 This example sets up two admin sites. On the first site, the
       
   530 ``Author`` and ``Publisher`` objects are exposed; ``Publisher``
       
   531 objects have an tabular inline showing books published by that
       
   532 publisher. The second site exposes just publishers, without the
       
   533 inlines.
       
   534 
       
   535 Using raw cursors with multiple databases
       
   536 =========================================
       
   537 
       
   538 If you are using more than one database you can use
       
   539 ``django.db.connections`` to obtain the connection (and cursor) for a
       
   540 specific database. ``django.db.connections`` is a dictionary-like
       
   541 object that allows you to retrieve a specific connection using it's
       
   542 alias::
       
   543 
       
   544     from django.db import connections
       
   545     cursor = connections['my_db_alias'].cursor()
       
   546 
       
   547 Limitations of multiple databases
       
   548 =================================
       
   549 
       
   550 .. _no_cross_database_relations:
       
   551 
       
   552 Cross-database relations
       
   553 ------------------------
       
   554 
       
   555 Django doesn't currently provide any support for foreign key or
       
   556 many-to-many relationships spanning multiple databases. If you
       
   557 have used a router to partition models to different databases,
       
   558 any foreign key and many-to-many relationships defined by those
       
   559 models must be internal to a single database.
       
   560 
       
   561 This is because of referential integrity. In order to maintain a
       
   562 relationship between two objects, Django needs to know that the
       
   563 primary key of the related object is valid. If the primary key is
       
   564 stored on a separate database, it's not possible to easily evaluate
       
   565 the validity of a primary key.
       
   566 
       
   567 If you're using Postgres, Oracle, or MySQL with InnoDB, this is
       
   568 enforced at the database integrity level -- database level key
       
   569 constraints prevent the creation of relations that can't be validated.
       
   570 
       
   571 However, if you're using SQLite or MySQL with MyISAM tables, there is
       
   572 no enforced referential integrity; as a result, you may be able to
       
   573 'fake' cross database foreign keys. However, this configuration is not
       
   574 officially supported by Django.