• Stars
    star
    313
  • Rank 133,714 (Top 3 %)
  • Language
    Python
  • License
    BSD 3-Clause "New...
  • Created almost 15 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Round-robin master/slave db router for Django.

django-multidb-router

Build Status

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

More Repositories

1

jingo

An adapter for using Jinja2 templates with Django.
Python
178
star
2

glow

(glow)$ gci -m 'glow is an application for counting firefox downloads'
Python
78
star
3

django-mobility

Middleware and decorators for directing users to your mobile site.
Python
60
star
4

check

Simple script to run pep8.py and pyflakes on a git/svn repo.
Python
42
star
5

tornado-websocket-client

Python
40
star
6

django-debug-cache-panel

A sweet little cache panel for django-debug-toolbar
Python
39
star
7

test-utils

A grab-bag of testing utilities that are pretty specific to our Django, Jinja2, and nose setup.
Python
33
star
8

push

Push notifications for the web
Python
30
star
9

schematic

The worst schema versioning system, ever?
Python
26
star
10

dotfiles

shell customizations gone awry
Vim Script
21
star
11

ribbons

Remaking the github ribbons in CSS
21
star
12

python-irclib

Fork of http://sourceforge.net/projects/python-irclib/, mainly so I can install it with pip.
Python
19
star
13

github-notifications

Push notifications for github
JavaScript
17
star
14

chief

development has moved to mozilla/chief
Python
16
star
15

vending-machine

a script for managing vendor libraries
Python
14
star
16

path.py

path.py provides a class (path) for working with files and directories. Less typing than os.path, more fun, a few new tricks.
12
star
17

reflecto

A tiny wsgi app to mirror github repos on a commit hook.
Python
9
star
18

push-addon

Firefox add-on implementing the push notfications API
JavaScript
9
star
19

git-tools

Scripts that make my git workflow smooth and tasty.
Python
9
star
20

bookmark-shortcut-keys

Firefox add-on that lets you access Bookmark Toolbar items with a keyboard shortcut
JavaScript
8
star
21

jetpacks

Features I have created for great good.
JavaScript
5
star
22

bosley

a british buildbot/ircbot for running AMO tests
Python
4
star
23

freddo

oremj's long-lost brother
Python
4
star
24

bots

hacky chatbots I threw together
JavaScript
3
star
25

moonshoes

moonshoes is a redirection service that will make your urls a lot longer.
Python
3
star
26

poboy

Extracts gettext fallbacks to messages.po, useful on AMO
Python
2
star
27

reredis

proxy redis connections so it's not a single point of failure
JavaScript
2
star
28

zurg

surely the world needs more static site generators
Python
2
star
29

pusher

push consumer
Python
2
star
30

freddo-lib

vendor lib for freddo
Python
2
star
31

bzattach

Uploading bugzilla attachments from the command line is the future!
Python
2
star
32

jbalogh.github.io

A website, on the Internet
CSS
2
star
33

bztools

Models and scripts to access the Bugzilla REST API.
2
star
34

modconcat

PHP helper functions for using mod_concat.
PHP
1
star
35

twttr

A twitter clone for a workshop in scalability. The poor performance is intentional.
Python
1
star