Repository: wagtail/wagtail

Issue:
Search: Make update_index update all backends
Currently, it only updates the default backend. It should update all search backends.



Discussion:

Resolving patch:
diff --git a/wagtail/wagtailsearch/management/commands/update_index.py b/wagtail/wagtailsearch/management/commands/update_index.py
--- a/wagtail/wagtailsearch/management/commands/update_index.py
+++ b/wagtail/wagtailsearch/management/commands/update_index.py
@@ -1,11 +1,22 @@
+from optparse import make_option
+
 from django.core.management.base import BaseCommand
 from django.db import models
+from django.conf import settings
 
 from wagtail.wagtailsearch import Indexed, get_search_backend
 
 
+def get_search_backends():
+    if hasattr(settings, 'WAGTAILSEARCH_BACKENDS'):
+        for backend in settings.WAGTAILSEARCH_BACKENDS.keys():
+            yield backend, get_search_backend(backend)
+    else:
+        yield 'default', get_search_backend('default')
+
+
 class Command(BaseCommand):
-    def handle(self, **options):
+    def get_object_list(self):
         # Print info
         self.stdout.write("Getting object list")
 
@@ -40,26 +51,51 @@ def handle(self, **options):
                     # Space free, take it
                     object_set[key] = obj
 
-        # Search backend
-        if 'backend' in options:
-            s = options['backend']
-        else:
-            s = get_search_backend()
+        return indexed_models, object_set.values()
+
+    def update_backend(self, backend, models, object_list, backend_name=''):
+        # Print info
+        self.stdout.write("Updating backend: " + backend_name)
+
+        # Get backend
+        if backend is None:
+            backend = get_search_backend(backend_name)
 
         # Reset the index
-        self.stdout.write("Reseting index")
-        s.reset_index()
+        self.stdout.write(backend_name + ": Reseting index")
+        backend.reset_index()
 
         # Add types
-        self.stdout.write("Adding types")
-        for model in indexed_models:
-            s.add_type(model)
+        self.stdout.write(backend_name + ": Adding types")
+        for model in models:
+            backend.add_type(model)
 
         # Add objects to index
-        self.stdout.write("Adding objects")
-        for result in s.add_bulk(object_set.values()):
+        self.stdout.write(backend_name + ": Adding objects")
+        for result in backend.add_bulk(object_list):
             self.stdout.write(result[0] + ' ' + str(result[1]))
 
         # Refresh index
-        self.stdout.write("Refreshing index")
-        s.refresh_index()
+        self.stdout.write(backend_name + ": Refreshing index")
+        backend.refresh_index()
+
+    option_list = BaseCommand.option_list + (
+        make_option('--backend',
+            action='store',
+            dest='backend_name',
+            default=False,
+            help="Specify a backend to update",
+        ),
+    )
+
+    def handle(self, **options):
+        # Get object list
+        models, object_list = self.get_object_list()
+
+        # Update backends
+        if 'backend_name' in options:
+            backend = dict(get_search_backends())[options['backend_name']]
+            self.update_backend(backend, models, object_list, backend_name=options['backend_name'])
+        else:
+            for backend_name, backend in get_search_backends():
+                self.update_backend(backend, models, object_list, backend_name=backend_name)


Test patch:
diff --git a/wagtail/wagtailsearch/tests/test_backends.py b/wagtail/wagtailsearch/tests/test_backends.py
--- a/wagtail/wagtailsearch/tests/test_backends.py
+++ b/wagtail/wagtailsearch/tests/test_backends.py
@@ -20,6 +20,7 @@ def setUp(self):
         for backend_name, backend_conf in settings.WAGTAILSEARCH_BACKENDS.items():
             if backend_conf['BACKEND'] == self.backend_path:
                 self.backend = get_search_backend(backend_name)
+                self.backend_name = backend_name
                 break
         else:
             # no conf entry found - skip tests for this backend
@@ -146,7 +147,7 @@ def test_update_index_command(self):
 
         # Run update_index command
         with self.ignore_deprecation_warnings():  # ignore any DeprecationWarnings thrown by models with old-style indexed_fields definitions
-            management.call_command('update_index', backend=self.backend, interactive=False, stdout=StringIO())
+            management.call_command('update_index', backend_name=self.backend_name, interactive=False, stdout=StringIO())
 
         # Check that there are still 3 results
         results = self.backend.search("Hello", models.SearchTest)