multi-db.txt 24 KB

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