為什么國內很少用django,Django如何使用多個數據庫

 2023-09-30 阅读 26 评论 0

摘要:1、定義數據庫(1) DATABASES內部選項:(2)自定義數據庫2、同步數據庫3、自動數據庫路由(1)定義數據庫路由方法類(2)使用路由數據庫(3)生成數據表并同步數據?4、手動選擇數據庫 1、定義數據庫 在
  • 1、定義數據庫
  • (1) DATABASES內部選項:
  • (2)自定義數據庫
  • 2、同步數據庫
  • 3、自動數據庫路由
  • (1)定義數據庫路由方法類
  • (2)使用路由數據庫
  • (3)生成數據表并同步數據
  • ?4、手動選擇數據庫

1、定義數據庫

在django項目中, 一個工程中存在多個APP應用很常見;有時候希望不同的APP連接不同的數據庫,這個時候需要建立多個數據庫連接。
在Django的setting中使用DATABASES設置定義數據庫,可以將數據庫映射到特定的別名字典中;DATABASES定義的是要給嵌套字典,該設置必須配置default默認數據庫。默認使用SQLite進行單一數據庫設置:
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': 'mydatabase',}
}

如不使用默認數據庫定義可以將默認配置為空字典形式:

'default':{}

(1) DATABASES內部選項:

ATOMIC_REQUESTS:為True時數據庫事務包裝每個視圖,默認為False

AUTOCOMMIT:為False時禁用Django事務管理,默認為True

為什么國內很少用django,ENGINE:設置數據庫類型

'django.db.backends.postgresql'
'django.db.backends.mysql'
'django.db.backends.sqlite3'
'django.db.backends.oracle'

HOST:指定連接的主機名或ip地址,如果使用(‘/’)正斜杠開頭則通過套接字連接:

'HOST':'127.0.0.1'   #TCP套接字連接
'HOST':'/var/run/mysql'   #UNIX套接字

NAME:制定使用的數據庫名,對于SQLite它是指定數據庫文件的路徑,在window上也要使用正斜杠。

'NAME':'databasename'
'NAME':'C:/user/mysite/sqlite3.db'

CONN_MAX_AGE:數據庫連接的生命周期,默認為0請求結束時關閉數據庫,設置為None無限持久連接。

OPTIONS:鏈接到數據庫時使用的額外參數,可用參數因數據庫類型而異。

'OPTIONS':{'read_default_file':'path/to/my.cnf',} #優先于NAME,USER,PASSWORD,HOST,PORT#設置mysql啟用嚴格模式
'OPTIONS':{'init_command':"SET sql_mode='STRICT_TRANS_TABLES'"}

PASSWORD:設置密碼,不與SQLite一起使用

django開發一個管理系統,PORT:指定端口

TIME_ZONE:設置時區

DISABLE_SERVER_SIDE_CURSORS:True時禁用服務器端游標

USER:鏈接用戶名

TEST:測試數據庫

(2)自定義數據庫

#自定義兩個mysql數據庫映射到db1和db2上
'db1':{'ENGINE': 'django.db.backends.mysql','NAME': 'db1','USER': 'root','PASSWORD': '123.com','HOST': '172.16.32.133','PORT': '3306','OPTIONS': {'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", },   #mysql使用嚴格模式,不指定會有警告信息},'db2':{'ENGINE': 'django.db.backends.mysql','NAME': 'db2','USER': 'root','PASSWORD': '123.com','HOST': '172.16.32.133','PORT': '3306','OPTIONS': {'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",}

django拿取已有數據庫的數據,如果訪問沒有在DATABASES中定義的數據庫,Django會報:django.db.utils.ConnectionDoesNotExist 異常。

2、同步數據庫

migrate管理命令會同時在每一個數據庫上運行,默認情況下它在default數據庫上運行 ,可以通過選項 --database來指定需要同步的數據庫。如不指定會同步到default數據庫上。

遷移同步命令:

makemigrations:根據簡稱到的變化創建新的遷移。migrate:將模型和遷移數據同步到數據庫中。

通過上面的列子,將每個應用程序同步到特定的數據庫:

#python manage.py migrate   #同步默認數據庫
#python manage.py migrate --database=db1
#python manage.py migrate --database=db2

多個數據庫導出:

python manage.py dumpdata app01 --database=db1 > app1_fixture.json
python manage.py dumpdata app02 --database=db2 > app2_fixture.json
python manage.py dumpdata auth > auth_fixture.json

多個數據庫導入:

python manage.py loaddata app1_fixture.json --database=db1
python manage.py loaddata app2_fixture.json --database=db2

3、自動數據庫路由

使用多個數據庫時最簡單的方法是設置數據庫路由方案,以保證對象對原始數據庫的“粘性",默認所有的查詢都會返回到default數據庫中。數據庫路由器是一個最多提供四種方法的類:db_for_read(model,**hints)  :應用于讀取類型對象的數據庫模型,如果數據庫提供附加信息會在hints字典中提供,最后如果沒有則返回Nonedb_for_write(model,**hints):應用于寫入類型對象的數據庫模型,hints字典提供附加信息,如果沒有則返回Noneallow_relation(obj1,obj2,**hints):外鍵操作,判斷兩個對象之間是否是應該允許關系,是返回True,否則返回False,如果路由允許返回Noneallow_migrate(db,app_label,model_name=None,**hints):db確定是否允許在具有別名的數據庫上運行遷移操作,操作運行返回True,否則返回False,或者返回None,如果路由器沒有意見。app_label:位置參數是正在遷移的應用程序的標簽。model_name:多個遷移操作設置模型的值,如:model._meta.app_label

flask和django的對比,(1)定義數據庫路由方法類

在項目工程根路徑下(與 settings.py 文件一級)創建數據庫路由表,app應用會根據指定的路由選擇數據庫:

app01,app02分別使用db1和db2數據庫:

#!/usr/bin/env python
#coding:utf8
from django.conf import settingsDATABASE_MAPPING = settings.DATABASE_APPS_MAPPING   #在setting中定義的路由表class DatabaseAppsRouter(object):def db_for_read(self, model, **hints):if model._meta.app_label in DATABASE_MAPPING:return DATABASE_MAPPING[model._meta.app_label]return Nonedef db_for_write(self, model, **hints):if model._meta.app_label in DATABASE_MAPPING:return DATABASE_MAPPING[model._meta.app_label]return Nonedef allow_relation(self, obj1, obj2, **hints):db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)if db_obj1 and db_obj2:if db_obj1 == db_obj2:return Trueelse:return Falsereturn Nonedef allow_syncdb(self, db, model):if db in DATABASE_MAPPING.values():return DATABASE_MAPPING.get(model._meta.app_label) == dbelif model._meta.app_label in DATABASE_MAPPING:return Falsereturn Nonedef allow_migrate(self, db, app_label, model_name=None, **hints):if db in DATABASE_MAPPING.values():return DATABASE_MAPPING.get(app_label) == dbelif app_label in DATABASE_MAPPING:return Falsereturn None

(2)使用路由數據庫

在setting.py中配置DATABASE_ROUTERS指定自由路由文件:

#test_django為項目名,database_router為路由文件名,DatabaseAppsRouter為路由中創建的類名DATABASE_ROUTERS = ['test_django.database_router.DatabaseAppsRouter']

在setting.py中DATABASE_ROUTERS下面設置app與數據庫匹配路由表,采用字典方式app名對應數據庫映射名:

DATABASE_APPS_MAPPING = {'app01':'db1','app02':'db2',}

django orm多表查詢、(3)生成數據表并同步數據

分別在app01和app02下創建model類,用于生成數據表:

app01:

from django.db import models# Create your models here.
class ap1(models.Model):username = models.CharField(max_length=30)class Meta:#app_label = 'app02'  #如果指定將在app02對應的數據庫下創建數據表class ap2(models.Model):first_name = models.CharField(max_length=50)last_name = models.CharField(max_length=50)birth_date = models.DateField()

app02:

from django.db import modelsclass ap3(models.Model):app2_name = models.CharField(max_length=50)sex = models.CharField(max_length=50)data = models.DateField()class ap4(models.Model):app2 = models.CharField(max_length=50)sex1 = models.CharField(max_length=50)data1 = models.DateField()class Meta:db_table = 'mytable' #自定義表名稱

migrate管理命令一次只能操作一個數據庫,默認操作default數據庫,使用--database指定同步的數據庫:

#python manage.py migrate  #生成表數據同步
#python manage.py makemigrations #創建變動數據
#python manage.py migrate --database=db1 #同步指定數據庫
#python manage.py migrate --database=db2

需要注意:在多個app分庫時,必須指定每個app對應的數據庫,否則在同步數據 庫時將沒指定的app模板都同步到同步數據庫中。

?4、手動選擇數據庫

laravel框架?使用using()指定查詢的數據庫的別名:

>>> # So will this.
>>> Author.objects.using('default').all()>>> # This will run on the 'other' database.
>>> Author.objects.using('other').all()

保存數據,Model.save()指定將數據保存到哪個數據庫中:

>>> my_object.save(using='legacy_users')#會將數據保存到legacy_users數據庫中,如不指定會保持到默認數據庫中。
>>> my_object.delete(using='legacy_users')
#刪除指定數據庫

移動對象到另一個數據庫時會發生主鍵沖突,可以使用obj.pk方法清除主鍵再保存對象。

>>> p = Person(name='Fred')
>>> p.save(using='first')
>>> p.pk = None # Clear the primary key.
>>> p.save(using='second') # Write a 

?

參考地址:https://www.cnblogs.com/zhangxinqi/p/9094953.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/106631.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息