新聞中心
Django也提供允許在代碼中完全控制數(shù)據(jù)庫的API。手動指定數(shù)據(jù)庫分配將優(yōu)先于路由分配的數(shù)據(jù)庫。

手動為查詢集選擇數(shù)據(jù)庫
你可以在查詢集鏈的任一點(diǎn)為查詢集選擇數(shù)據(jù)庫。調(diào)用查詢集上的 ?using()? 就可以獲取使用指定數(shù)據(jù)庫的其他查詢集。
?using()? 使用單一參數(shù):你打算進(jìn)行查詢的數(shù)據(jù)庫別名。比如:
>>> # 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()為保存選擇數(shù)據(jù)庫
使用 ?using?關(guān)鍵字來 ?Model.save()? 到指定的數(shù)據(jù)保存的數(shù)據(jù)庫。
比如,要保存對象到 ?legacy_users數(shù)據(jù)庫,你應(yīng)該這樣寫:
>>> my_object.save(using='legacy_users')如果你沒有指定 ?using?,?save()? 方法將保存到路由的默認(rèn)數(shù)據(jù)庫分配。
將對象從一個數(shù)據(jù)庫移動到另一個
如果已經(jīng)保存實(shí)例到數(shù)據(jù)庫,它可能使用 ?save(using=...)? 作為遷移實(shí)例到新數(shù)據(jù)庫的方法。然而,如果沒有使用適合的步驟,這可能會產(chǎn)生意想不到的結(jié)果。
考慮下面的例子:
>>> p = Person(name='Fred')
>>> p.save(using='first') # (statement 1)
>>> p.save(using='second') # (statement 2)在語句1,新的 ?Person?對象保存在 ?first?數(shù)據(jù)庫。這一次,?p?沒有主鍵,因此 Django 發(fā)出了一個SQL ?INSERT?語句。這會創(chuàng)建主鍵,并且 Django 分配那個主鍵到 ?p?。
在語句2中進(jìn)行保存時,?p?也有主鍵值,Django 將試圖在新的數(shù)據(jù)庫上使用主鍵。如果主鍵值未在 ?second?數(shù)據(jù)庫中使用,那么將不會有任何問題——對象將被拷貝到新數(shù)據(jù)庫。
然而,如果 ?p?的主鍵已經(jīng)在 ?second?數(shù)據(jù)庫上使用,那么當(dāng)保存 ?p?的時候, ?second?數(shù)據(jù)庫中存在的對象將被覆蓋。
可以通過兩種方式避免這種情況。首先,可以清理實(shí)例主鍵。如果對象沒有主鍵,那么 Django 將它作為新對象來處理,避免在 ?second?數(shù)據(jù)庫上造成任何數(shù)據(jù)丟失:
>>> p = Person(name='Fred')
>>> p.save(using='first')
>>> p.pk = None # Clear the primary key.
>>> p.save(using='second') # Write a completely new object.第二個辦法就是使用 ?force_insert?選項(xiàng)來 ?save()? ,確保 Django 執(zhí)行了 SQL ?INSERT?:
>>> p = Person(name='Fred')
>>> p.save(using='first')
>>> p.save(using='second', force_insert=True)這將確保 ?Fred?在兩個數(shù)據(jù)庫上擁有同一個主鍵。當(dāng)試著在 ?second?上保存時,如果主鍵已經(jīng)保存,那么將會引發(fā)一個錯誤。
選擇要刪除的數(shù)據(jù)庫
默認(rèn)情況下,用來刪除現(xiàn)有對象的調(diào)用將在用于首先檢索對象的同一數(shù)據(jù)庫上執(zhí)行:
>>> u = User.objects.using('legacy_users').get(username='fred')
>>> u.delete() # will delete from the `legacy_users` database指定將要刪除模型的數(shù)據(jù)庫,傳遞 ?using?關(guān)鍵字參數(shù)到 ?Model.delete()? 方法。這個參數(shù)的工作方式與用關(guān)鍵字參數(shù) ?save()? 是一樣的。
例如,如果你正在從 ?legacy_users?遷移用戶到 ?new_users?數(shù)據(jù)庫,你可以使用這些命令:
>>> user_obj.save(using='new_users')
>>> user_obj.delete(using='legacy_users')使用多個數(shù)據(jù)庫管理器
在管理器上使用 ?db_manager()? 方法來讓管理員訪問非默認(rèn)數(shù)據(jù)庫。
比如,假設(shè)有一個自定義管理器方法來觸發(fā)數(shù)據(jù)庫——?User.objects.create_user()?。因?yàn)??create_user()? 是一個管理器方法,不是 ?QuerySet?方法,你不能操作 ?User.objects.using('new_users').create_user()? 。(?create_user()? 方法只適用 ?User.objects? ,即管理器,而不是來自管理器上的 ?QuerySet?。)解決方案是使用 ?db_manager()? ,像這樣:
User.objects.db_manager('new_users').create_user(...)?db_manager()? 返回綁定到指定數(shù)據(jù)庫的管理器副本。
將 get_queryset() 和多個數(shù)據(jù)庫使用
如果在管理器上覆蓋了 ?get_queryset()? ,請確保在父類上調(diào)用這個方法使用 ?super()? 或者在管理器(包含使用的數(shù)據(jù)庫的名字)上適當(dāng)處理 ?_db? 屬性。
比如,如果你想從 ?get_queryset? 方法返回自定義的 ?QuerySet?類,你可以這樣做:
class MyManager(models.Manager):
def get_queryset(self):
qs = CustomQuerySet(self.model)
if self._db is not None:
qs = qs.using(self._db)
return qs 當(dāng)前文章:創(chuàng)新互聯(lián)Django4.0教程:Django4.0 多數(shù)據(jù)庫-手動選擇數(shù)據(jù)庫
瀏覽路徑:http://www.dlmjj.cn/article/djposde.html


咨詢
建站咨詢
