multi-db.txt 29 KB

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