首頁 web前端 js教程 Django如何使用多資料庫方法介紹

Django如何使用多資料庫方法介紹

Sep 07, 2017 am 10:17 AM
django 資料庫 方法

有些项目可能涉及到使用多个数据库的情况,方法很简单。接下来通过本文给大家介绍Django使用多数据库的方法,需要的朋友参考下吧

有些项目可能涉及到使用多个数据库的情况,方法很简单。

1.在settings中设定DATABASE

比如要使用两个数据库:


DATABASES = {
  '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'
  }
}
登入後複製

这样就确定了2个数据库,别名一个为default,一个为user。数据库的别名可以任意确定。

default的别名比较特殊,一个Model在路由中没有特别选择时,默认使用default数据库。

当然,default也可以设置为空:


DATABASES = {
  'default': {},
  'users': {
    'NAME': 'user_data',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_user',
    'PASSWORD': 'superS3cret'
  },
  'customers': {
    'NAME': 'customer_data',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_cust',
    'PASSWORD': 'veryPriv@ate'
  }
}
登入後複製

这样,因为没有了默认的数据库,就需要为所有的Model,包括使用的第三方库中的Model做好数据库路由选择。

2.为需要做出数据库选择的Model规定app_label


class MyUser(models.Model):
  ...
  class Meta:
    app_label = 'users'
登入後複製

3.写Database Routers

Database Router用来确定一个Model使用哪一个数据库,主要定义以下四个方法:

db_for_read(model, **hints)

规定model使用哪一个数据库读取。

db_for_write(model, **hints)

规定model使用哪一个数据库写入。

allow_relation(obj1, obj2, **hints)

确定obj1和obj2之间是否可以产生关联, 主要用于foreign key和 many to many操作。

allow_migrate(db, app_label, model_name=None, **hints)

确定migrate操作是否可以在别名为db的数据库上运行。

一个完整的例子:

数据库设定:


DATABASES = {
  'default': {},
  'auth_db': {
    'NAME': 'auth_db',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_user',
    'PASSWORD': 'swordfish',
  },
  'primary': {
    'NAME': 'primary',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_user',
    'PASSWORD': 'spam',
  },
  'replica1': {
    'NAME': 'replica1',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_user',
    'PASSWORD': 'eggs',
  },
  'replica2': {
    'NAME': 'replica2',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_user',
    'PASSWORD': 'bacon',
  },
}
登入後複製

如果想要达到如下效果:

app_label为auth的Model读写都在auth_db中完成,其余的Model写入在primary中完成,读取随机在replica1和replica2中完成。

auth:


class AuthRouter(object):
  """
  A router to control all database operations on models in the
  auth application.
  """
  def db_for_read(self, model, **hints):
    """
    Attempts to read auth models go to auth_db.
    """
    if model._meta.app_label == 'auth':
      return 'auth_db'
    return None
  def db_for_write(self, model, **hints):
    """
    Attempts to write auth models go to auth_db.
    """
    if model._meta.app_label == 'auth':
      return 'auth_db'
    return None
  def allow_relation(self, obj1, obj2, **hints):
    """
    Allow relations if a model in the auth app is involved.
    """
    if obj1._meta.app_label == 'auth' or \
      obj2._meta.app_label == 'auth':
      return True
    return None
  def allow_migrate(self, db, app_label, model_name=None, **hints):
    """
    Make sure the auth app only appears in the 'auth_db'
    database.
    """
    if app_label == 'auth':
      return db == 'auth_db'
    return None
登入後複製

这样app_label为auth的Model读写都在auth_db中完成,允许有关联,migrate只在auth_db数据库中可以运行。

其余的:


import random
class PrimaryReplicaRouter(object):
  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_list = ('primary', 'replica1', 'replica2')
    if obj1._state.db in db_list and obj2._state.db in db_list:
      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
登入後複製

这样读取在随机在replica1和replica2中完成,写入使用primary。

最后在settings中设定:


DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.PrimaryReplicaRouter']
登入後複製

就可以了。

进行migrate操作时:


$ ./manage.py migrate
$ ./manage.py migrate --database=users
登入後複製

migrate操作默认对default数据库进行操作,要对其它数据库进行操作,可以使用--database选项,后面为数据库的别名。

与此相应的,dbshell,dumpdata,loaddata命令都有--database选项。

也可以手动的选择路由:

查询:


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

保存:


>>> my_object.save(using='legacy_users')
登入後複製

移动:


>>> p = Person(name='Fred')
>>> p.save(using='first') # (statement 1)
>>> p.save(using='second') # (statement 2)
登入後複製

以上的代码会产生问题,当p在first数据库中第一次保存时,会默认生成一个主键,这样使用second数据库保存时,p已经有了主键,这个主键如果未被使用不会产生问题,但如果先前被使用了,就会覆盖原先的数据。

有两个解决方法;

1.保存前清除主键:


>>> p = Person(name='Fred')
>>> p.save(using='first')
>>> p.pk = None # Clear the primary key.
>>> p.save(using='second') # Write a completely new object.
登入後複製

2.使用force_insert


>>> p = Person(name='Fred')
>>> p.save(using='first')
>>> p.save(using='second', force_insert=True)
登入後複製

删除:

从哪个数据库取得的对象,从哪删除


>>> u = User.objects.using('legacy_users').get(username='fred')
>>> u.delete() # will delete from the `legacy_users` database
登入後複製

如果想把一个对象从legacy_users数据库转移到new_users数据库:


>>> user_obj.save(using='new_users')
>>> user_obj.delete(using='legacy_users')
登入後複製

以上是Django如何使用多資料庫方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

微信刪除的人如何找回(簡單教學告訴你如何恢復被刪除的聯絡人) 微信刪除的人如何找回(簡單教學告訴你如何恢復被刪除的聯絡人) May 01, 2024 pm 12:01 PM

而後悔莫及、人們常常會因為一些原因不小心刪除某些聯絡人、微信作為一款廣泛使用的社群軟體。幫助用戶解決這個問題,本文將介紹如何透過簡單的方法找回被刪除的聯絡人。 1.了解微信聯絡人刪除機制這為我們找回被刪除的聯絡人提供了可能性、微信中的聯絡人刪除機制是將其從通訊錄中移除,但並未完全刪除。 2.使用微信內建「通訊錄恢復」功能微信提供了「通訊錄恢復」節省時間和精力,使用者可以透過此功能快速找回先前刪除的聯絡人,功能。 3.進入微信設定頁面點選右下角,開啟微信應用程式「我」再點選右上角設定圖示、進入設定頁面,,

手機版龍蛋孵化方法大揭密(一步一步教你如何成功孵化手機版龍蛋) 手機版龍蛋孵化方法大揭密(一步一步教你如何成功孵化手機版龍蛋) May 04, 2024 pm 06:01 PM

手機遊戲成為了人們生活中不可或缺的一部分,隨著科技的發展。它以其可愛的龍蛋形象和有趣的孵化過程吸引了眾多玩家的關注,而其中一款備受矚目的遊戲就是手機版龍蛋。幫助玩家們在遊戲中更好地培養和成長自己的小龍,本文將向大家介紹手機版龍蛋的孵化方法。 1.選擇合適的龍蛋種類玩家需要仔細選擇自己喜歡並且適合自己的龍蛋種類,根據遊戲中提供的不同種類的龍蛋屬性和能力。 2.提升孵化機的等級玩家需要透過完成任務和收集道具來提升孵化機的等級,孵化機的等級決定了孵化速度和孵化成功率。 3.收集孵化所需的資源玩家需要在遊戲中

手機字體大小設定方法(輕鬆調整手機字體大小) 手機字體大小設定方法(輕鬆調整手機字體大小) May 07, 2024 pm 03:34 PM

字體大小的設定成為了重要的個人化需求,隨著手機成為人們日常生活的重要工具。以滿足不同使用者的需求、本文將介紹如何透過簡單的操作,提升手機使用體驗,調整手機字體大小。為什麼需要調整手機字體大小-調整字體大小可以使文字更清晰易讀-適合不同年齡段用戶的閱讀需求-方便視力不佳的用戶使用手機系統自帶字體大小設置功能-如何進入系統設置界面-在在設定介面中找到並進入"顯示"選項-找到"字體大小"選項並進行調整第三方應用調整字體大小-下載並安裝支援字體大小調整的應用程式-開啟應用程式並進入相關設定介面-根據個人

iOS 18 新增「已復原」相簿功能 可找回遺失或損壞的照片 iOS 18 新增「已復原」相簿功能 可找回遺失或損壞的照片 Jul 18, 2024 am 05:48 AM

蘋果公司最新發布的iOS18、iPadOS18以及macOSSequoia系統為Photos應用程式增添了一項重要功能,旨在幫助用戶輕鬆恢復因各種原因遺失或損壞的照片和影片。這項新功能在Photos應用的"工具"部分引入了一個名為"已恢復"的相冊,當用戶設備中存在未納入其照片庫的圖片或影片時,該相冊將自動顯示。 "已恢復"相簿的出現為因資料庫損壞、相機應用未正確保存至照片庫或第三方應用管理照片庫時照片和視頻丟失提供了解決方案。使用者只需簡單幾步

在PHP中使用MySQLi建立資料庫連線的詳盡教學 在PHP中使用MySQLi建立資料庫連線的詳盡教學 Jun 04, 2024 pm 01:42 PM

如何在PHP中使用MySQLi建立資料庫連線:包含MySQLi擴充(require_once)建立連線函數(functionconnect_to_db)呼叫連線函數($conn=connect_to_db())執行查詢($result=$conn->query())關閉連線( $conn->close())

如何選擇手機膜,保護你的手機螢幕(選購手機膜的幾個重點與技巧) 如何選擇手機膜,保護你的手機螢幕(選購手機膜的幾個重點與技巧) May 07, 2024 pm 05:55 PM

手機膜成為了必不可少的配件之一,隨著智慧型手機的普及。延長其使用壽命,選擇合適的手機膜可以保護手機螢幕。幫助讀者選出最適合自己的手機膜、本文將介紹選購手機膜的幾個重點與技巧。了解手機膜的材質及類型PET膜,TPU等、手機膜有多種材質,包括強化玻璃。 PET膜較為柔軟、強化玻璃膜具有較好的耐刮花性能,TPU則具有較好的防震性能。可根據個人偏好及需求來決定,在選擇時。考慮螢幕的保護程度不同類型的手機膜對螢幕的保護程度不同。 PET膜則主要起防刮花作用,強化玻璃膜具有較好的耐摔性能。可以選擇具有較好

如何在PHP中處理資料庫連線錯誤 如何在PHP中處理資料庫連線錯誤 Jun 05, 2024 pm 02:16 PM

PHP處理資料庫連線報錯,可以使用下列步驟:使用mysqli_connect_errno()取得錯誤代碼。使用mysqli_connect_error()取得錯誤訊息。透過擷取並記錄這些錯誤訊息,可以輕鬆識別並解決資料庫連接問題,確保應用程式的順暢運作。

快速去除老人斑的有效方法(教你簡單又快速消除老人斑的養膚秘訣) 快速去除老人斑的有效方法(教你簡單又快速消除老人斑的養膚秘訣) May 03, 2024 pm 12:01 PM

頸部和手背等暴露部位,老年斑是一種常見的皮膚問題,往往出現在年長者的臉部。也會讓人看起來顯老、它不僅帶給人們的外表困擾。隨著科技的進步和美容技術的發展,現在有了許多簡單而快速的方法來祛除老年斑,然而。恢復年輕又健康的肌膚、幫助您快速消除老年斑、本文將分享一些有效的養膚秘訣。 1.積極保護皮膚免受紫外線傷害的重要性所以避免長時間暴露在陽光下是非常重要的、紫外線是導致老年斑形成的主要原因之一。 2.合理選擇護膚產品,使用含有抗氧化劑和美白成分的產品護膚產品中含有抗氧化劑和美白成分可以幫助減少老年斑的形

See all articles