Ich habe einen einzigen Sellerie Arbeiter mit 5 Fäden. Es scrappt Webseiten und speichert Domains über djangos ORM in der DB.Sellerie/Django doppelte Schlüsselverletzungen
Hier grob ist, wie es aussieht:
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)
Wahrscheinlich nicht der beste Weg, aber es überprüft Domains in einem dict (dup_free_scrape) gegen alle Domains bereits in der Datenbank.
Es kann Hunderte gehen oder sogar Tausende vor den Fehler zu stoßen, aber manchmal tut es:
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"
Der einzige Grund für dieses Problem, das ich von wäre denken kann: Ein Thread gespeichert Domäne DB, während ein anderer war in der Mitte des Codes oben?
Ich kann keine guten Lösungen finden, aber hier ist und Idee (nicht sicher, ob etwas gut): Wrap ganze Sache in der Transaktion und wenn Datenbank Fehler Fehler simply Wiederholung (Abfrage-Datenbank für "Domain.objects.all() " nochmal).
macht sehr viel Sinn, aber keine Abfrage Datenbank viel get_or_create? Weil manchmal mehr als 100 Domains hinzugefügt werden. Danke – JanRainMan
Es wird aber 100 Abfragen werden wahrscheinlich effizienter als das Durchlaufen der gesamten Tabelle, die Hunderttausende haben könnte. – e4c5
Außerdem haben Sie im ursprünglichen Code tatsächlich eine verschachtelte Schleife aufgrund der Überprüfung jeder Bedingung. – e4c5