Skip to main content

Round-robin multidb router for Django.

Project description

django-multidb-router

Build Status https://img.shields.io/pypi/v/django-multidb-router.svg

multidb provides two Django database routers useful in primary-replica database deployments.

ReplicaRouter

With multidb.ReplicaRouter all read queries will go to a replica database; all inserts, updates, and deletes will go to the default database.

First, define REPLICA_DATABASES in your settings. It should be a list of database aliases that can be found in DATABASES:

DATABASES = {
    'default': {...},
    'shadow-1': {...},
    'shadow-2': {...},
}
REPLICA_DATABASES = ['shadow-1', 'shadow-2']

Then put multidb.ReplicaRouter into DATABASE_ROUTERS:

DATABASE_ROUTERS = ('multidb.ReplicaRouter',)

The replica databases will be chosen in round-robin fashion.

If you want to get a connection to a replica in your app, use multidb.get_replica:

from django.db import connections
import multidb

connection = connections[multidb.get_replica()]

PinningReplicaRouter

In some applications, the lag between the primary database receiving a write and its replication to the replicas is enough to cause inconsistency for the end user. For example, imagine a scenario with 1 second of replication lag. If a user makes a forum post (to the primary) and then is redirected to a fully-rendered view of it (from a replica) 500ms later, the view will fail. If this is a problem in your application, consider using multidb.PinningReplicaRouter. This router works in combination with multidb.middleware.PinningRouterMiddleware to assure that, after writing to the default database, future reads from the same user agent are directed to the default database for a configurable length of time.

Caveats

PinningRouterMiddleware identifies database writes primarily by request type, assuming that requests with HTTP methods that are not GET, TRACE, HEAD, or OPTIONS are writes. You can indicate that any view writes to the database by using the multidb.db_write decorator. This will cause the same result as if the request were, e.g., a POST.

You can also manually set response._db_write = True to indicate that a write occurred. This will not result in using the default database in this request, but only in the next request.

Configuration

To use PinningReplicaRouter, put it into DATABASE_ROUTERS in your settings:

DATABASE_ROUTERS = ('multidb.PinningReplicaRouter',)

Then, install the middleware. It must be listed before any other middleware which performs database writes:

MIDDLEWARE_CLASSES = (
    'multidb.middleware.PinningRouterMiddleware',
    ...more middleware here...
)

PinningRouterMiddleware attaches a cookie to any user agent who has just written. The cookie should be set to expire at a time longer than your replication lag. By default, its value is a conservative 15 seconds, but it can be adjusted like so:

MULTIDB_PINNING_SECONDS = 5

If you need to change the name of the cookie, use the MULTIDB_PINNING_COOKIE setting:

MULTIDB_PINNING_COOKIE = 'multidb_pin_writes'

You may also set the ‘Secure’, ‘HttpOnly’, and ‘SameSite’ cookie attributes by using the following settings. These settings are based on Django’s settings for the session and CSRF cookies:

MULTIDB_PINNING_COOKIE_SECURE = False
MULTIDB_PINNING_COOKIE_HTTPONLY = False
MULTIDB_PINNING_COOKIE_SAMESITE = 'Lax'

Note: the ‘SameSite’ attribute is only available on django 2.1 and higher.

use_primary_db

multidb.pinning.use_primary_db is both a context manager and a decorator for wrapping code to use the primary database. You can use it as a context manager:

from multidb.pinning import use_primary_db

with use_primary_db:
    touch_the_database()
touch_another_database()

or as a decorator:

from multidb.pinning import use_primary_db

@use_primary_db
def func(*args, **kw):
    """Touches the primary database."""

Running the Tests

To run the tests, you’ll need to install the development requirements:

pip install -r requirements.txt
./run.sh test

Alternatively, you can run the tests with several versions of Django and Python using tox:

$ pip install tox

$ tox

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-multidb-router-0.10.tar.gz (9.1 kB view details)

Uploaded Source

Built Distribution

django_multidb_router-0.10-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file django-multidb-router-0.10.tar.gz.

File metadata

  • Download URL: django-multidb-router-0.10.tar.gz
  • Upload date:
  • Size: 9.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.5

File hashes

Hashes for django-multidb-router-0.10.tar.gz
Algorithm Hash digest
SHA256 a10bf4b664465090a5f2e8543dd1491eaf8dde7c551270e546324454e7280964
MD5 6d85337e9f5aa06565ee79a2892c5dda
BLAKE2b-256 ad95ad33d474a299ed0917dafb701027806f76b48e657c923756da0e3944d2bf

See more details on using hashes here.

File details

Details for the file django_multidb_router-0.10-py3-none-any.whl.

File metadata

  • Download URL: django_multidb_router-0.10-py3-none-any.whl
  • Upload date:
  • Size: 10.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.5

File hashes

Hashes for django_multidb_router-0.10-py3-none-any.whl
Algorithm Hash digest
SHA256 6802bbfce3a0dac343f93a290df12a9979aed99b350bc0148a7430353efae8b6
MD5 ef77c53b02f4bfd6dc61b2ae4e482c81
BLAKE2b-256 84050983a9627858c1a95726e6df8af6e20f358a689ee54785391486fe8264fc

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page