当前位置:Gxlcms > 数据库问题 > Django配置数据库读写分离

Django配置数据库读写分离

时间:2021-07-01 10:21:17 帮助过:5人阅读

: { ‘ENGINE‘: ‘django.db.backends.sqlite3‘, ‘NAME‘: os.path.join(BASE_DIR, ‘db.sqlite3‘), }, ‘db2‘: { ‘ENGINE‘: ‘django.db.backends.sqlite3‘, ‘NAME‘: os.path.join(BASE_DIR, ‘db2.sqlite3‘), }, }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

创建models并执行数据库迁移

这里我简单创建一张产品表

  1. <code class="language-python hljs has-numbering"><span class="hljs-keyword">from</span> django.db <span class="hljs-keyword">import</span> models
  2. <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Products</span><span class="hljs-params">(models.Model)</span>:</span>
  3. <span class="hljs-string">"""产品表"""</span>
  4. prod_name = models.CharField(max_length=<span class="hljs-number">30</span>)
  5. prod_price = models.DecimalField(max_digits=<span class="hljs-number">6</span>, decimal_places=<span class="hljs-number">2</span>)</code>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

创建完成后,执行数据库迁移操作:

  1. <code class="language-shell hljs avrasm has-numbering">python manage<span class="hljs-preprocessor">.py</span> makemigrations <span class="hljs-preprocessor"># 在migrations文件夹下生成记录,迁移前检查</span>
  2. python manage<span class="hljs-preprocessor">.py</span> migrate <span class="hljs-preprocessor"># 创建表</span></code>
  • 1
  • 2

在migrations文件夹下生成记录,并在迁移前检查是否有问题,默认值检查defualt数据库,但是可以在后面的数据库路由类(Router)中通过allow_migrate()方法来指定是否检查其它的数据库。

其实第二步迁移默认有参数python manage.py migrate --database default ,在默认数据库上创建表。因此完成以上迁移后,执行python manage.py --database db2,再迁移一次,就可以在db2上创建相同的表。这样在项目根目录下,就有了两个表结构一样的数据库,分别是db.sqlite3和db2.sqlite3。

读写分离

手动读写分离

在使用数据库时,通过.using(db_name)来手动指定要使用的数据库

  1. <code class="language-python hljs has-numbering"><span class="hljs-keyword">from</span> django.shortcuts <span class="hljs-keyword">import</span> HttpResponse
  2. <span class="hljs-keyword">from</span> . <span class="hljs-keyword">import</span> models
  3. <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write</span><span class="hljs-params">(request)</span>:</span>
  4. models.Products.objects.using(<span class="hljs-string">‘default‘</span>).create(prod_name=<span class="hljs-string">‘熊猫公仔‘</span>, prod_price=<span class="hljs-number">12.99</span>)
  5. <span class="hljs-keyword">return</span> HttpResponse(<span class="hljs-string">‘写入成功‘</span>)
  6. <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read</span><span class="hljs-params">(request)</span>:</span>
  7. obj = models.Products.objects.filter(id=<span class="hljs-number">1</span>).using(<span class="hljs-string">‘db2‘</span>).first()
  8. <span class="hljs-keyword">return</span> HttpResponse(obj.prod_name)</code>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

自动读写分离

通过配置数据库路由,来自动实现,这样就不需要每次读写都手动指定数据库了。数据库路由中提供了四个方法。这里这里主要用其中的两个:def db_for_read()决定读操作的数据库,def db_for_write()决定写操作的数据库。

定义Router类

新建myrouter.py脚本,定义Router类:

  1. <code class="language-python hljs has-numbering"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Router</span>:</span>
  2. <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">db_for_read</span><span class="hljs-params">(self, model, **hints)</span>:</span>
  3. <span class="hljs-keyword">return</span> <span class="hljs-string">‘db2‘</span>
  4. <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">db_for_write</span><span class="hljs-params">(self, model, **hints)</span>:</span>
  5. <span class="hljs-keyword">return</span> <span class="hljs-string">‘default‘</span></code>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
配置Router

settings.py中指定DATABASE_ROUTERS

  1. <code class="language-python hljs has-numbering">DATABASE_ROUTERS = [<span class="hljs-string">‘myrouter.Router‘</span>,] </code>
  • 1

可以指定多个数据库路由,比如对于读操作,Django将会循环所有路由中的db_for_read()方法,直到其中一个有返回值,然后使用这个数据库进行当前操作。

一主多从方案

网站的读的性能通常更重要,因此,可以多配置几个数据库,并在读取时,随机选取,比如:

  1. <code class="language-python hljs has-numbering"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Router</span>:</span>
  2. <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">db_for_read</span><span class="hljs-params">(self, model, **hints)</span>:</span>
  3. <span class="hljs-string">"""
  4. 读取时随机选择一个数据库
  5. """</span>
  6. <span class="hljs-keyword">import</span> random
  7. <span class="hljs-keyword">return</span> random.choice([<span class="hljs-string">‘db2‘</span>, <span class="hljs-string">‘db3‘</span>, <span class="hljs-string">‘db4‘</span>])
  8. <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">db_for_write</span><span class="hljs-params">(self, model, **hints)</span>:</span>
  9. <span class="hljs-string">"""
  10. 写入时选择主库
  11. """</span>
  12. <span class="hljs-keyword">return</span> <span class="hljs-string">‘default‘</span></code>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

分库分表

在大型web项目中,常常会创建多个app来处理不同的业务,如果希望实现app之间的数据库分离,比如app01走数据库db1,app02走数据库

  1. <code class="language-python hljs has-numbering"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Router</span>:</span>
  2. <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">db_for_read</span><span class="hljs-params">(self, model, **hints)</span>:</span>
  3. <span class="hljs-keyword">if</span> model._meta.app_label == <span class="hljs-string">‘app01‘</span>:
  4. <span class="hljs-keyword">return</span> <span class="hljs-string">‘db1‘</span>
  5. <span class="hljs-keyword">if</span> model._meta.app_label == <span class="hljs-string">‘app02‘</span>:
  6. <span class="hljs-keyword">return</span> <span class="hljs-string">‘db2‘</span>
  7. <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">db_for_write</span><span class="hljs-params">(self, model, **hints)</span>:</span>
  8. <span class="hljs-keyword">if</span> model._meta.app_label == <span class="hljs-string">‘app01‘</span>:
  9. <span class="hljs-keyword">return</span> <span class="hljs-string">‘db1‘</span>
  10. <span class="hljs-keyword">if</span> model._meta.app_label == <span class="hljs-string">‘app02‘</span>:
  11. <span class="hljs-keyword">return</span> <span class="hljs-string">‘db2‘</span></code>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

 

更多请参考官网

Django配置数据库读写分离

标签:function   port   processor   char   目的   sqlite3   参数   multi   using   

人气教程排行