This is hopefully an easy question.
I'm having some trouble understanding the documentation for the new multiple database feature in Django 1.2. Primarily, I cant seem to find an example of how you actually USE the second database in one of your models.
When I define a new class in my models.py how do I specify which database I intend on connecting to?
My settings.py contains something similar to -
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'modules',
'USER': 'xxx',
'PASSWORD': 'xxx',
},
'asterisk': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'users',
'USER': 'xxxx',
'PASSWORD': 'xxxx',
}
}
Edit: I was reading the documentation on routers like a dummy. If anyone else is struggling with this just make sure you read it 2 or 3 times before giving up!
Django's admin doesn't have any explicit support for multiple databases. If you want to provide an admin interface for a model on a database other than that specified by your router chain, you'll need to write custom ModelAdmin classes that will direct the admin to use a specific database for content.
Yeah, it is a little bit complicated.
There are a number of ways you could implement it. Basically, you need some way of indicating which models are associated with which database.
Here's the code that I use; hope it helps.
from django.db import connections
class DBRouter(object):
"""A router to control all database operations on models in
the contrib.auth application"""
def db_for_read(self, model, **hints):
m = model.__module__.split('.')
try:
d = m[-1]
if d in connections:
return d
except IndexError:
pass
return None
def db_for_write(self, model, **hints):
m = model.__module__.split('.')
try:
d = m[-1]
if d in connections:
return d
except IndexError:
pass
return None
def allow_syncdb(self, db, model):
"Make sure syncdb doesn't run on anything but default"
if model._meta.app_label == 'myapp':
return False
elif db == 'default':
return True
return None
The way this works is I create a file with the name of the database to use that holds my models. In your case, you'd create a separate models
-style file called asterisk.py
that was in the same folder as the models for your app.
In your models.py
file, you'd add
from asterisk import *
Then when you actually request a record from that model, it works something like this:
records = MyModel.object.all()
MyModel
is myapp.asterisk
If you want to have per-model control of database choice, something like this would work:
from django.db import connections
class DBRouter(object):
"""A router to control all database operations on models in
the contrib.auth application"""
def db_for_read(self, model, **hints):
if hasattr(model,'connection_name'):
return model.connection_name
return None
def db_for_write(self, model, **hints):
if hasattr(model,'connection_name'):
return model.connection_name
return None
def allow_syncdb(self, db, model):
if hasattr(model,'connection_name'):
return model.connection_name
return None
Then for each model:
class MyModel(models.Model):
connection_name="asterisk"
#etc...
Note that I have not tested this second option.
An addendum to Jordans answer above. For the second option, the allow_syncdb method works correctly as follows:
def allow_syncdb(self, db, model):
if hasattr(model,'connection_name'):
return model.connection_name == db
return db == 'default'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With