2012-05-29 44 views
10

我的Django的bulk_create讀了和幾個「瑕疵」的:在外鍵中使用Django的bulk_create對象?

" 
This has a number of caveats though: 

1. The model's save() method will not be called, and the pre_save and post_save signals will not be sent. 
2. It does not work with child models in a multi-table inheritance scenario. 
3. If the model's primary key is an AutoField it does not retrieve and set the primary key attribute, as save() does. 
" 

我沒有完全理解它。所以,如果我有對象的列表,將其傳遞給bulk_create:

objList = [a, b, c,] #none are saved 
model.objects.bulk_create(objList) 

難道我還使用外鍵精細這些對象呢?

for obj in objList: 
    o = otherModel(something='asdfasdf', fkey=obj) 
    o.save() # will this be fine given the caveats stated above? 

那麼外鍵關係會好嗎?當它說2.它不適用於多表繼承場景中的子模型,這意味着任何從另一個模型繼承的模型(抽象與否)都不能使用bulk_create?

回答

2

對於第一個問題,不會有這樣做,因爲obj將不會有其主鍵集,因此不能用作外鍵。

第二個問題,沒有那不是它說的。它特別提到「多表繼承」:從抽象模型繼承不是多表繼承。

+0

那麼我將如何處理外鍵關係?我是否必須查詢數據庫以選擇我剛剛插入的對象? – Derek

+0

你應該完全避免'bulk_create'在你的情況下。只需單獨創建對象。 –

+7

那麼你如何建議處理性能問題與個人保存? – Derek

5

嘗試手動設置ID。爲了防止競爭條件,請確保將該功能作爲單個事務處理。

from django.db import transaction, models 

@transaction.commit_on_success 
def bulk_create_with_manual_ids(foo_list): 
    id_start = (Foo.objects.all().aggregate(models.Max('id'))['id__max'] or 0) + 1 
    for i,foo in enumerate(foo_list): foo.id = id_start + i 
    return Foo.objects.bulk_create(foo_list) 

objList = [Foo(),Foo(),Foo()] 
foo_objects = bulk_create_with_manual_ids(objList) 
Bar(foo=foo_objects[0]).save() 

注意,這種方法不適用於具有serial場或任何其他表自動遞增的數據庫生成的密鑰。由於在Django端生成ID,密鑰不會因批量創建而增加。

+0

這是醜陋的,但它的作品! –

+0

單筆交易是否足以避免任何競爭條件?這是完全安全的嗎? – kissgyorgy

+3

我已經upvoted,但我應該downvoted! id字段在數據庫中不會自動增加。這是一個巨大的問題。 –