Repository: mozilla/pontoon

Issue:
Store pretranslations for each locale separately
We currently retrieve pretranslations for each locale separately, and store them all at once with a single DB query (for all locales). That makes our DB performance a little bit better, but risks the need for additional retrieval of already retrieved pretranslations in case of an error.

Since retrieving pretranslations is significantly slower than writing them to the DB, we should write to DB for each locale separately.


Discussion:

Resolving patch:
diff --git a/pontoon/pretranslation/tasks.py b/pontoon/pretranslation/tasks.py
--- a/pontoon/pretranslation/tasks.py
+++ b/pontoon/pretranslation/tasks.py
@@ -105,16 +105,16 @@ def pretranslate(self, project_pk, locales=None, entities=None):
 
     translated_entities = list(translated_entities)
 
-    translations = []
+    for locale in locales:
+        log.info(f"Fetching pretranslations for locale {locale.code} started")
 
-    # To keep track of changed TranslatedResources and their latest_translation
-    tr_dict = {}
+        translations = []
 
-    tr_filter = []
-    index = -1
+        # To keep track of changed TranslatedResources and their latest_translation
+        tr_dict = {}
+        tr_filter = []
+        index = -1
 
-    for locale in locales:
-        log.info(f"Fetching pretranslations for locale {locale.code} started")
         for entity in entities:
             locale_entity = f"{locale.id}-{entity.id}"
             locale_resource = f"{locale.id}-{entity.resource.id}"
@@ -165,39 +165,42 @@ def pretranslate(self, project_pk, locales=None, entities=None):
                 # Update the latest translation index
                 tr_dict[locale_resource] = index
 
-        log.info(f"Fetching pretranslations for locale {locale.code} done")
+        if len(translations) == 0:
+            log.info(
+                f"Fetching pretranslations for locale {locale.code} done: No pretranslation fetched"
+            )
+            continue
 
-    if len(translations) == 0:
-        return
+        translations = Translation.objects.bulk_create(translations)
 
-    translations = Translation.objects.bulk_create(translations)
+        # Log creating actions
+        actions_to_log = [
+            ActionLog(
+                action_type=ActionLog.ActionType.TRANSLATION_CREATED,
+                performed_by=t.user,
+                translation=t,
+            )
+            for t in translations
+        ]
 
-    # Log creating actions
-    actions_to_log = [
-        ActionLog(
-            action_type=ActionLog.ActionType.TRANSLATION_CREATED,
-            performed_by=t.user,
-            translation=t,
-        )
-        for t in translations
-    ]
+        ActionLog.objects.bulk_create(actions_to_log)
 
-    ActionLog.objects.bulk_create(actions_to_log)
+        # Run checks on all translations
+        translation_pks = {translation.pk for translation in translations}
+        bulk_run_checks(Translation.objects.for_checks().filter(pk__in=translation_pks))
 
-    # Run checks on all translations
-    translation_pks = {translation.pk for translation in translations}
-    bulk_run_checks(Translation.objects.for_checks().filter(pk__in=translation_pks))
+        # Mark translations as changed
+        changed_translations = Translation.objects.filter(
+            pk__in=translation_pks,
+            # Do not sync translations with errors and warnings
+            errors__isnull=True,
+            warnings__isnull=True,
+        )
+        changed_translations.bulk_mark_changed()
 
-    # Mark translations as changed
-    changed_translations = Translation.objects.filter(
-        pk__in=translation_pks,
-        # Do not sync translations with errors and warnings
-        errors__isnull=True,
-        warnings__isnull=True,
-    )
-    changed_translations.bulk_mark_changed()
+        # Update latest activity and stats for changed instances.
+        update_changed_instances(tr_filter, tr_dict, translations)
 
-    # Update latest activity and stats for changed instances.
-    update_changed_instances(tr_filter, tr_dict, translations)
+        log.info(f"Fetching pretranslations for locale {locale.code} done")
 
     log.info(f"Fetching pretranslations for project {project.name} done")


Test patch: