我有一個單線程的5個芹菜工人。它通過django的ORM抓取網站並將域名保存到數據庫。芹菜/ django重複關鍵違規
這裏大致是它的樣子:
domain_all = list(Domain.objects.all())
needs_domain = set()
for x in dup_free_scrape:
domain = x['domain']
if any(domain.lower() == s.name.lower() for s in domain_all):
x['domainn'] = [o for o in domain_all if domain.lower() == o.name.lower()][0]
else:
print('adding: {}'.format(domain))
needs_domain.add(domain)
create_domains = [Domain(name=b.lower()) for b in needs_domain]
create_domains_ids = Domain.objects.bulk_create(create_domains)
可能不是最好的方式,但它在一個字典(dup_free_scrape)針對已經在數據庫中的所有域檢查域。
它可以走了幾百甚至上千遇到錯誤之前,但有時它的作用:
Task keywords.domains.model_work[285c3e74-8e47-4925-9ab6-a99540a24665] raised unexpected: IntegrityError('duplicate key value violates unique constraint "keywords_domain_name_key"\nDETAIL: Key (name)=(domain.com) already exists.\n',) django.db.utils.IntegrityError: duplicate key value violates unique constraint "keywords_domain_name_key"
對於這個問題,我能想到的唯一理由是:一個線程保存域DB,而另一個是在上面的代碼中間?我不能找到任何好的解決方案,但這裏是和想法(不知道是否有任何好處):在事務中包裝整個事情,如果數據庫引發錯誤簡單重試(查詢數據庫爲「Domain.objects.all() 「再次)。
有很多意義,但不會get_or_create查詢數據庫很多嗎?因爲有時它在時間上添加了超過100個域名。謝謝 – JanRainMan
只有100個查詢可能比循環整個可能有數十萬個表的查詢更有效率。 – e4c5
除了在原始代碼中,由於任何條件檢查,您實際上都有嵌套循環。 – e4c5