django数据库读写分离
django数据库读写分离
1. 配置数据库
settings.py文件中用SQLite:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }, 'salve': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'), }, }
或者用mysql:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', 'PORT': 3306, 'USER': 'user', 'PASSWORD': 'passwd', 'NAME': 'db_read' }, 'slave': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', 'PORT': 8306, 'USER': 'root', 'PASSWORD': 'mysqlpwd', 'NAME': 'db_write' } }
2.创建models并执行数据库迁移(略)
3.操作读写分离
- 手动读写分离
------views.py视图文件中------ object.using(‘default’) 这里指定用哪个库, from django.shortcuts import HttpResponse from . import models def write(request): models.Products.objects.using('default').create(name='毛毛', age=12) return HttpResponse('写入成功') def read(request): obj = models.Products.objects.filter(id=1).using('salve').first() return HttpResponse(obj.name)
- 自动读写分离
通过配置数据库路由,来自动实现。新建router.py文件
class Router: def db_for_read(self, model, **hints): ''' db_for_read固定写法,读操作自动匹配 ''' return 'slave' def db_for_write(self, model, **hints): ''' db_for_write固定写法,写操作自动匹配 ''' return 'default'
配置router
------settings.py------文件中 DATABASE_ROUTERS = ['router.Router',]
4.一主多从方案
新建router.py文件class Router: def db_for_read(self, model, **hints): """ 读取时随机选择一个数据库 """ import random return random.choice(['salve1', 'slave2', 'slave3']) def db_for_write(self, model, **hints): """ 写入时选择主库 """ return 'default'
配置router
------settings.py------文件中 DATABASE_ROUTERS = ['router.Router',]
5.分库分表
新建router.py文件app之间的数据库分离,比如app01走数据库salve1,app02走数据库slave2
class Router: def db_for_read(self, model, **hints): if model._meta.app_label == 'app01': return 'salve1' if model._meta.app_label == 'app02': return 'slave2' def db_for_write(self, model, **hints): if model._meta.app_label == 'app01': return 'slave1' if model._meta.app_label == 'app02': return 'slave2'
配置router
------settings.py------文件中 DATABASE_ROUTERS = ['router.Router',]
配置注意事项:
python manage.py makemigraions python manage.py migrate app名称 --databse=配置文件数据名称的别名 手动操作: models.UserType.objects.using('db1').create(title='普通用户') result = models.UserType.objects.all().using('default') 自动操作: class Router1: def db_for_read(self, model, **hints): """ Attempts to read auth models go to auth_db. """ return 'db1' def db_for_write(self, model, **hints): """ Attempts to write auth models go to auth_db. """ return 'default' 配置: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }, 'db1': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db1.sqlite3'), }, } DATABASE_ROUTERS = ['db_router.Router1',] 使用: models.UserType.objects.create(title='VVIP') result = models.UserType.objects.all() print(result) 补充:粒度更细 class Router1: def db_for_read(self, model, **hints): """ Attempts to read auth models go to auth_db. """ if model._meta.model_name == 'usertype': return 'db1' else: return 'default' def db_for_write(self, model, **hints): """ Attempts to write auth models go to auth_db. """ return 'default' 问题: app01中的表在default数据库创建 app02中的表在db1数据库创建 # 第一步: python manage.py makemigraions # 第二步: app01中的表在default数据库创建 python manage.py migrate app01 --database=default # 第三步: app02中的表在db1数据库创建 python manage.py migrate app02 --database=db1 # 手动操作: m1.UserType.objects.using('default').create(title='VVIP') m2.Users.objects.using('db1').create(name='VVIP',email='xxx') # 自动操作: 配置: class Router1: def db_for_read(self, model, **hints): """ Attempts to read auth models go to auth_db. """ if model._meta.app_label == 'app01': return 'default' else: return 'db1' def db_for_write(self, model, **hints): """ Attempts to write auth models go to auth_db. """ if model._meta.app_label == 'app01': return 'default' else: return 'db1' DATABASE_ROUTERS = ['db_router.Router1',] 使用: m1.UserType.objects.using('default').create(title='VVIP') m2.Users.objects.using('db1').create(name='VVIP',email='xxx') 其他: 数据库迁移时进行约束: class Router1: def allow_migrate(self, db, app_label, model_name=None, **hints): """ All non-auth models end up in this pool. """ if db=='db1' and app_label == 'app02': return True elif db == 'default' and app_label == 'app01': return True else: return False # 如果返回None,那么表示交给后续的router,如果后续没有router,则相当于返回True def db_for_read(self, model, **hints): """ Attempts to read auth models go to auth_db. """ if model._meta.app_label == 'app01': return 'default' else: return 'db1' def db_for_write(self, model, **hints): """ Attempts to write auth models go to auth_db. """ if model._meta.app_label == 'app01': return 'default' else: return 'db1' docker run -it -p 8000:8000 --name=mydemo -v /home/test/:/usr/lqz my_django_test python /usr/lqz/djangotest2/manage.py runserver 0.0.0.0:8000 docker run -it -p 8000:8000 --name=mydemo_lqz_django -v /home/test/:/usr/lqz lqz_django_v1 python /usr/lqz/djangotest2/manage.py runserver 0.0.0.0:8000
本文来自博客园,作者:游走De提莫,转载请注明原文链接:https://www.cnblogs.com/Gaimo/p/12177485.html