Using Multiple Databases With Django
Solution 1:
To use multiple databases you have to tell Django about the database server you will be using, but adding them in the settings.py.
'default': {
'NAME': 'app_data',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'postgres_user',
'PASSWORD': 's3krit'
},
'users': {
'NAME': 'user_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'priv4te'
}
}
The migrate management command operates on one database at a time. By default, it operates on the default database, but by providing the --database option, you can tell it to synchronize a different database.
$ ./manage.py migrate --database=users$ ./manage.py migrate --database=customers
You can manually select the database in your queries queries e.g
user=User(....)
user.save(using='users')
Customer.objects.all().using('users')
Using raw cursor
with connections['users'].cursor() as cursor:
cursor.execute("SELECT * FROM users__users")
Solution 2:
As far as I know, your models can see the database, but aren't using 'accounts' database because it's set to use 'default' db. You can change this by creating custom database router.
Here, I am assuming that your directory structure for django project is:
./mainapp/
|--- mainapp/
| |--- settings.py
| |___ # .....
|
|--- app/
| |--- apps.py
| |--- dbrouters.py # [new file], we will be creating soon.
| |--- models.py
| |--- views.py
| |___ # .....
|
|--- manage.py
|___ # .....
Full example:
# app/models.py:classAccounts (models.Model):
# .....# app/dbrouters.py: # [new file]from .models import Accounts
classAccountsDBRouter:
defdb_for_read (self, model, **hints):
if (model == Accounts):
# your model name as in settings.py/DATABASESreturn'accounts'returnNonedefdb_for_write (self, model, **hints):
if (model == Accounts):
# your model name as in settings.py/DATABASESreturn'accounts'returnNone# mainapp/settings.py:# .....
INSTALLED_APPS = [
'app.apps.AppConfig',
# .....
]
# .....
DATABASE_ROUTERS = (
'app.dbrouters.AccountsDBRouter',
)
DATABASES = {
# .....'accounts' : {
# .....
},
}
# .....
Change the above code as per your requirement or specifications.
Then, do the following:
$ python3 manage.py makemigrations
$ python3 manage.py migrate --database=accounts
$ python3 manage.py migrate
Now, you should be able to use it without using('accounts')
in code as follows:
# app/views.py:# .....from .models import Accounts
defsomeview (request):
accounts = Accounts.objects.all()
# See, in above line, you're not using:# accounts = Accounts.objects.using('accounts').all()# as your 'AccountsDBRouter' is already routing read and write# db requests to 'accounts' database.# Though you can still use "using('accounts')", as it will# also provide same results.defsomeotherview (request):
# You can even use the following:
account = Account(
email="<email>",
phone="<phone>",
# .....
)
account.save()
# Again, this will save directly in 'accounts'.
References:
- DBRouter and code - https://stackoverflow.com/a/47896031
- DBRouters django docs - https://docs.djangoproject.com/en/3.2/topics/db/multi-db/#using-routers
- DBRouters methods django docs - https://docs.djangoproject.com/en/3.2/topics/db/multi-db/#database-routers
Hope that answers you. :)
Solution 3:
You have to route queries to the database too (emphasis is mine):
The easiest way to use multiple databases is to set up a database routing scheme. The default routing scheme ensures that objects remain ‘sticky’ to their original database (i.e., an object retrieved from the foo database will be saved on the same database).
The default routing scheme ensures that if a database isn’t specified, all queries fall back to the default database.
https://docs.djangoproject.com/en/2.1/topics/db/multi-db/#automatic-database-routing
NB: the db_table
in your model's Meta is for the name of the database table, not the name of the database itself !-)
Post a Comment for "Using Multiple Databases With Django"