Django 也提供一個可讓你經過代碼徹底控制數據庫使用的 API 。手動定義數據庫分配 優先於路由。數據庫
你能夠在 查詢集 「鏈」中的任何點爲 查詢集 選擇數據庫。咱們經過在 查詢集 上調用 using() 來獲得使用指定數據庫的另外一個 查詢集 。spa
using() 使用一個參數:你想要運行查詢的數據庫的別名。例如:對象
>>> # 這會運行在「缺省」數據庫上。 >>> Author.objects.all() >>> # 這一樣會運行在「缺省」數據庫上。 >>> Author.objects.using('default').all() >>> # 這會運行在「 other 」數據庫上。 >>> Author.objects.using('other').all()
在使用 Model.save() 時加上 using 關鍵字能夠指定保存到哪一個數據庫。路由
例如,要把一個對象保存到 legacy_users 數據庫應該這樣作:字符串
>>> my_object.save(using='legacy_users')
若是你不定義 using ,那麼 save() 方法會根據路由分配把數據保存到缺省 數據庫中。get
當你已經在一個數據庫中保存了一個對象後,你可能會使用 save(using=...) 把這個 對象移動到另外一個數據庫中。可是,若是你沒有使用恰當的方法,那麼可能會出現意想不 到的後果。class
假設有以下的例子:object
>>> p = Person(name='Fred') >>> p.save(using='first') # (第一句) >>> p.save(using='second') # (第二名)
在第一名中,一個新的 Person 對象被保存到 first 數據庫中。這時, p 尚未一個主鍵,所以 Django 執行了一個INSERT SQL 語句。這樣就會建立一個 主鍵,並將這個主鍵分配給 p 。model
在第二句中,由於 p 已經有了一個主鍵,因此 Django 在保存對象時會嘗試在新的 數據庫中使用這個主鍵。若是 second數據庫中沒有使用這個主鍵,那就不會有問題, 該對象會複製到新數據庫。方法
然而,若是 p 的主鍵在 second 數據庫中已經使用過了,那麼 second 使用 這個主鍵的已存在的對象將會被 p 覆蓋。
有兩種方法能夠避免上述狀況的發生。第一,你能夠清除實例的主鍵。若是一個對象沒有 主主鍵,那麼 Django 會把它看做一個新對象,在保存到 second 數據庫中時就不會 帶來數據的損失:
>>> p = Person(name='Fred') >>> p.save(using='first') >>> p.pk = None # 清除主鍵。 >>> p.save(using='second') # 寫入一個全新的對象。
第二種方法是在 save() 方法中使用 force_insert 選項來保證 Django 執行 一個 INSERT SQL:
>>> p = Person(name='Fred') >>> p.save(using='first') >>> p.save(using='second', force_insert=True)
這樣能夠保證名爲 Fred 的人員在兩個數據庫中使用相同的主鍵。若是在保存到 second 數據庫時主鍵已被佔用,會拋出一個錯誤。
缺省狀況下,一個現存對象從哪一個數據庫獲得,刪除這個對象也會在這個數據庫中進行:
>>> u = User.objects.using('legacy_users').get(username='fred') >>> u.delete() # 會從 `legacy_users` 數據庫中刪除
經過向 Model.delete() 方法傳遞 using 關鍵字參數能夠定義在哪一個數據庫中刪除 數據。 using 的用法與 save() 方法中使用這個參數相似。
例如,假設咱們要把一個用戶從 legacy_users 數據庫移動到 new_users 數據庫 可使用以下命令:
>>> user_obj.save(using='new_users') >>> user_obj.delete(using='legacy_users')
在管理器上使用 db_manager() ,可讓管理器訪問一個非缺省數據庫。
例如,假設你有一個操做數據庫的自定義管理器 User.objects.create_user() 。 由於 create_user() 是一個管理器方法,不是一個 查詢集 ,因此你不能用 User.objects.using('new_users').create_user() 。( create_user() 方法 只能用於 User.objects 管理器,而不能用於,管理器衍生出的 查詢集 。) 解決方法是使用 db_manager() ,就象下面這樣:
User.objects.db_manager('new_users').create_user(...)
db_manager() 返回的是綁定到你指定的數據庫的管理器的一個副本。
若是你在管理器中重載了 get_query_set() ,請確保在其父類中也調用了相同的方法 (使用 super() )或者正確處理管理器中的 _db 屬性(一個包含要使用的數據庫 名稱的字符串)。
例如,若是你要從 get_query_set 方法返回一個自定義 查詢集 類,那麼你能夠 這樣作:
class MyManager(models.Manager): def get_query_set(self): qs = CustomQuerySet(self.model) if self._db is not None: qs = qs.using(self._db) return qs