Skip to content

Instantly share code, notes, and snippets.

@mindlace
Created October 16, 2012 15:31
Show Gist options
  • Save mindlace/3900005 to your computer and use it in GitHub Desktop.
Save mindlace/3900005 to your computer and use it in GitHub Desktop.
Multi-DB madness.
import django.contrib.auth.signals.user_logged_in
import django.contrib.auth.signals.user_logged_out
from django.core.signals import request_finished
from django.dispatch import receiver
from django.conf import settings
import logging
class HellRouter(object):
"""
A router to control all database operations on models in the
legacy application on a per-user basis.
"""
def __init__(self):
self.active_dbs = {}
self.active_user = None
user_logged_out.connect(handle_logout)
user_logged_in.connect(handle_login)
def handle_login(self, sender, request, user):
#use sender to figure out whether they're the right kind of user...
profile = user.get_profile()
settings.DATABASES[user.username] = {
'ENGINE': 'django.db.backends.microsoft.something',
'USER': profile.db_user,
'NAME': profile.db_name,
'PASSWORD': profile.db_pass
}
def handle_logout(self, sender, request, user):
if user.username in self.active_dbs:
del settings.DATABASES[user.username]
@receiver(request_finished)
def deactivate_user(self, sender, **kwargs):
if active_user is not None:
self.active_user = None
def pave_road_to(user):
if self.active_user is not user:
log = logging.get_logger(__name__)
log.warning("%s being displaced for %s, madness may ensue" % (self.active_user.username, user.username))
self.active_user = user
def db_for_read(self, model, **hints):
"""
Attempts to read legacy models go to legacy_db.
"""
if model._meta.app_label == 'legacy':
return self.active_user.username
return None
def db_for_write(self, model, **hints):
"""
Attempts to write legacy models go to legacy_db.
"""
if model._meta.app_label == 'legacy':
return self.actie_user.username
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the legacy app is involved.
"""
if obj1._meta.app_label == 'legacy' or \
obj2._meta.app_label == 'legacy':
return True
return None
def allow_syncdb(self, db, model):
"""
Make sure the legacy app only appears in the 'legacy_db'
database.
"""
if db == 'legacy_db':
return model._meta.app_label == 'legacy'
elif model._meta.app_label == 'legacy':
return False
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment