django配置多个db
如下,配置两个数据库:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
"HOST": "xxxx",
"PORT": "xxx",
'USER': 'postgres_user',
'PASSWORD': 's3krit',
'NAME': 'app_data',
},
'users': {
'ENGINE': 'django.db.backends.mysql',
"HOST": "xxx",
"PORT": 3306,
'USER': 'mysql_user',
'PASSWORD': 'priv4te',
'NAME': 'users_data',
}
}
迁移时,一次操作一个数据库:
python manage.py migrate
python manage.py migrate --database=users
默认的数据库,不使用时,可以配置一个空字典,但必须得定义,如下:
DATABASES = {
'default': {},
'users': {
'ENGINE': 'django.db.backends.mysql',
"HOST": "xx",
"PORT": 3306,
'USER': 'mysql_user',
'PASSWORD': 'superS3cret',
'NAME': 'user_data',
},
'customers': {
'ENGINE': 'django.db.backends.mysql',
"HOST": "xxx",
"PORT": "3306",
'USER': 'mysql_cust',
'PASSWORD': 'veryPriv@ate',
'NAME': 'customer_data',
}
}
此时,必须定义模型类的数据库路由 ?
数据库路由
在主应用下创建database_router.py,内部定义数据库路由类。 数据库路由是一个类,提供如下四个方法: db_for_read(model, **hints),模型类对象的读取
db_for_write(model, **hints),模型类对象的写入
allow_relation(obj1, obj2, **hints),表关系
allow_migrate(db, app_label, model_name=None, **hints), 是否允许迁移
1. 安装数据库路由:
DATABASES = {
'default': {},
'auth_db': {
'NAME': 'auth_db_name',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'swordfish',
},
'primary': {
'NAME': 'primary_name',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'spam',
},
'replica1': {
'NAME': 'replica1_name',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'eggs',
},
'replica2': {
'NAME': 'replica2_name',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'bacon',
},
}
DATABASE_ROUTERS = ["project_name.database_router.AuthRouter", "xxx"]
2. 定义数据库路由
class AuthRouter:
"""
A router to control all database operations on models in the
auth and contenttypes applications.
"""
route_app_labels = {'auth', 'contenttypes'}
def db_for_read(self, model, **hints):
"""
Attempts to read auth and contenttypes models go to auth_db.
"""
if model._meta.app_label in self.route_app_labels:
return 'auth_db'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write auth and contenttypes models go to auth_db.
"""
if model._meta.app_label in self.route_app_labels:
return 'auth_db'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the auth or contenttypes apps is
involved.
"""
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
Make sure the auth and contenttypes apps only appear in the
'auth_db' database.
app_label, 表示使用的数据库别名
"""
if app_label in self.route_app_labels:
return db == 'auth_db'
return None
import random
class PrimaryReplicaRouter:
def db_for_read(self, model, **hints):
"""
Reads go to a randomly-chosen replica.
"""
return random.choice(['replica1', 'replica2'])
def db_for_write(self, model, **hints):
"""
Writes always go to primary.
"""
return 'primary'
def allow_relation(self, obj1, obj2, **hints):
"""
Relations between objects are allowed if both objects are
in the primary/replica pool.
"""
db_set = {'primary', 'replica1', 'replica2'}
if obj1._state.db in db_set and obj2._state.db in db_set:
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
All non-auth models end up in this pool.
"""
return True
在配置文件中,加入如下:
DATABASE_ROUTERS = ['project_name.database_router.AuthRouter', 'project_name.database_router。PrimaryReplicaRouter']
还需为应用下的模型类,指定使用的数据库:
class User(models.Model):
...
class Meta:
db_table = "user"
managed = True
app_label = "users"
python manage.py makemigratins users
python manage.py migrate users --database=auth_db
手动选择一个db
CRUD可以通过using(“xxx”)指定数据库, 优先级高于数据库路由
>>>
>>> Author.objects.all()
>>> Author.objects.using('default').all()
>>>
>>> Author.objects.using('other').all()
>>> my_object.save(using='users_db')
>>> p = Person(name='Fred')
>>> p.save(using='firstDB')
>>> p.save(using='secondDB')
>>> p.pk = None
>>> p.save(using='second')
或者采用强制插入的方式:
>>> p.save(using='second', force_insert=True)
>>> user_obj.save(using='new_users')
>>> user_obj.delete(using='legacy_users')
>>> User.objects.db_manager('users_db').create_user(...)
django官网配置多个db
|