2016-05-29 3 views
1

私は5スレッドの単一のセロリ労働者があります。 djangoのORMを使用してウェブサイトを掘り起こし、ドメインをDBに保存しています。それがどのように見えるかここでセロリー/ 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) 

ない最良の方法、それは既にデータベース内のすべてのドメインに対して1つのdictの(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"

唯一の理由は、次のようになります。他の一方で1つのスレッドがDBにドメインを保存上記のコードの真中にありましたか?

私は良い解決策を見つけることができませんが、ここに、アイデアがあります(良いかどうかわからない場合):トランザクションで全部をラップし、databaiseがエラーを発生させた場合単純な再試行( "Domain.objects.all()もう一度)。

答えて

0

これらのレコードをバルクで作成していて、複数のスレッドがある場合は、同じデータを挿入する異なるスレッドによって発生することが実際にあります。これには複数のスレッドが必要ですか?はいの場合は試してみてください

create_domains = [] 
create_domain_ids = [] 

for x in dup_free_scrape: 
    domain = x['domain'] 
    new_domain, created = Domain.objects.get_or_create(name = domain.lower() 
    if created: 
     create_domains.append(domain.lower()) 
     created_domain_ids.append(new_domain.pk) 

注:これはすべてコードです。あなたが最初に持っていたすべての選択クエリは、必要ではありません。 Domain.objects.all()は、テーブル全体を読み込んでいるため、非常に非効率的になります。

また、x['domainn']のリストの理解は完全に冗長であるように見えます。

create_domainsおよびcreate_domain_ids作成する内容を把握しない限り、リストは必要ない場合があります。

ドメイン名に適切なインデックスがあることを確認してください。 get_or_createからdocs:

+0

多くの意味合いがありますが、多くのクエリデータベースが作成されませんか?時には、時には100以上のドメインを追加することもあるためです。ありがとう – JanRainMan

+0

それは100のクエリはおそらく数十万を持つ可能性があります全体のテーブルをループするよりも効率的になります。 – e4c5

+0

元のコードに加えて、実際には任意の条件チェックのためにネストされたループがあります。 – e4c5

関連する問題