55import sys
66from argparse import ArgumentParser
77from collections import defaultdict
8+ from datetime import datetime
89from typing import Any , Callable
910
1011import opensearchpy
1718from django_opensearch_dsl .registries import registry
1819from ..enums import OpensearchAction
1920from ..types import parse
21+ from ...documents import Document
2022
2123
2224class Command (BaseCommand ):
@@ -54,19 +56,40 @@ def __list_index(self, **options): # noqa pragma: no cover
5456 indices = registry .get_indices ()
5557 result = defaultdict (list )
5658 for index in indices :
57- module = index ._doc_types [0 ].__module__ .split ("." )[- 2 ] # noqa
59+ document = index ._doc_types [0 ]
60+ module = document .__module__ .split ("." )[- 2 ] # noqa
5861 exists = index .exists ()
5962 checkbox = f"[{ 'X' if exists else ' ' } ]"
60- count = f" ({ index .search ().count ()} documents)" if exists else ""
61- result [module ].append (f"{ checkbox } { index ._name } { count } " )
63+ document_indices = document .get_all_indices ()
64+ if document_indices :
65+ details = ". Following indices exist:"
66+ for document_index in document_indices :
67+ is_active = ""
68+ if document_index .exists_alias (name = index ._name ):
69+ is_active = self .style .SUCCESS ("Active" )
70+ count = f" ({ document_index .search ().count ()} documents)"
71+ details += f"\n - { document_index ._name } { is_active } { count } "
72+ elif exists :
73+ details = f" ({ index .search ().count ()} documents)"
74+ else :
75+ details = ""
76+ result [module ].append (f"{ checkbox } { index ._name } { details } " )
6277 for app , indices in result .items ():
6378 self .stdout .write (self .style .MIGRATE_LABEL (app ))
6479 self .stdout .write ("\n " .join (indices ))
6580
66- def _manage_index (self , action , indices , force , verbosity , ignore_error , ** options ): # noqa
81+ def _manage_index (self , action , indices , suffix , force , verbosity , ignore_error , ** options ): # noqa
6782 """Manage the creation and deletion of indices."""
6883 action = OpensearchAction (action )
69- known = registry .get_indices ()
84+
85+ suffix = suffix or datetime .now ().strftime ("%Y%m%d%H%M%S%f" )
86+
87+ if action == OpensearchAction .CREATE :
88+ known = registry .get_indices ()
89+ else :
90+ known = []
91+ for document in [i ._doc_types [0 ] for i in registry .get_indices ()]:
92+ known .extend (document .get_all_indices ())
7093
7194 # Filter indices
7295 if indices :
@@ -84,9 +107,15 @@ def _manage_index(self, action, indices, force, verbosity, ignore_error, **optio
84107
85108 # Display expected action
86109 if verbosity or not force :
110+ if not indices :
111+ self .stdout .write ("Nothing to do, exiting" )
112+ exit (0 )
87113 self .stdout .write (f"The following indices will be { action .past } :" )
88114 for index in indices :
89- self .stdout .write (f"\t - { index ._name } ." ) # noqa
115+ index_name = index ._name # noqa
116+ if action == OpensearchAction .CREATE :
117+ index_name += f"{ Document .VERSION_NAME_SEPARATOR } { suffix } "
118+ self .stdout .write (f"\t - { index_name } ." ) # noqa
90119 self .stdout .write ("" )
91120
92121 # Ask for confirmation to continue
@@ -101,23 +130,21 @@ def _manage_index(self, action, indices, force, verbosity, ignore_error, **optio
101130
102131 pp = action .present_participle .title ()
103132 for index in indices :
133+ index_name = index ._name # noqa
134+ if action == OpensearchAction .CREATE :
135+ index_name += f"{ Document .VERSION_NAME_SEPARATOR } { suffix } "
136+
104137 if verbosity :
105138 self .stdout .write (
106- f"{ pp } index '{ index . _name } '...\r " ,
139+ f"{ pp } index '{ index_name } '...\r " ,
107140 ending = "" ,
108141 ) # noqa
109142 self .stdout .flush ()
110143 try :
111144 if action == OpensearchAction .CREATE :
112- index .create ( )
145+ index ._doc_types [ 0 ]. init ( suffix = suffix )
113146 elif action == OpensearchAction .DELETE :
114147 index .delete ()
115- else :
116- try :
117- index .delete ()
118- except opensearchpy .exceptions .NotFoundError :
119- pass
120- index .create ()
121148 except opensearchpy .exceptions .NotFoundError :
122149 if verbosity or not ignore_error :
123150 self .stderr .write (f"{ pp } index '{ index ._name } '...{ self .style .ERROR ('Error (not found)' )} " ) # noqa
@@ -127,17 +154,17 @@ def _manage_index(self, action, indices, force, verbosity, ignore_error, **optio
127154 except opensearchpy .exceptions .RequestError :
128155 if verbosity or not ignore_error :
129156 self .stderr .write (
130- f"{ pp } index '{ index ._name } '... { self .style .ERROR ('Error (already exists) ' )} "
157+ f"{ pp } index '{ index ._name } '... { self .style .ERROR ('Error' )} "
131158 ) # noqa
132159 if not ignore_error :
133160 self .stderr .write ("exiting..." )
134161 exit (1 )
135162 else :
136163 if verbosity :
137- self .stdout .write (f"{ pp } index '{ index . _name } '... { self .style .SUCCESS ('OK' )} " ) # noqa
164+ self .stdout .write (f"{ pp } index '{ index_name } '... { self .style .SUCCESS ('OK' )} " ) # noqa
138165
139166 def _manage_document (
140- self , action , indices , force , filters , excludes , verbosity , parallel , count , refresh , missing , ** options
167+ self , action , indices , index_suffix , force , filters , excludes , verbosity , parallel , count , refresh , missing , ** options
141168 ): # noqa
142169 """Manage the creation and deletion of indices."""
143170 action = OpensearchAction (action )
@@ -206,7 +233,9 @@ def _manage_document(
206233 document = index ._doc_types [0 ]() # noqa
207234 qs = document .get_indexing_queryset (stdout = self .stdout ._out , verbose = verbosity , action = action , ** kwargs )
208235 success , errors = document .update (
209- qs , parallel = parallel , refresh = refresh , action = action , raise_on_error = False
236+ qs , action ,
237+ parallel = parallel , index_suffix = index_suffix ,
238+ refresh = refresh , raise_on_error = False
210239 )
211240
212241 success_str = self .style .SUCCESS (success ) if success else success
@@ -241,23 +270,23 @@ def add_arguments(self, parser):
241270 )
242271 subparser .set_defaults (func = self .__list_index )
243272
244- # 'manage ' subcommand
273+ # 'index ' subcommand
245274 subparser = subparsers .add_parser (
246275 "index" ,
247- help = "Manage the creation an deletion of indices." ,
248- description = "Manage the creation an deletion of indices." ,
276+ help = "Manage the deletion of indices." ,
277+ description = "Manage the deletion of indices." ,
249278 )
250279 subparser .set_defaults (func = self ._manage_index )
251280 subparser .add_argument (
252281 "action" ,
253282 type = str ,
254- help = "Whether you want to create, delete or rebuild the indices." ,
283+ help = "Whether you want to create or delete the indices." ,
255284 choices = [
256285 OpensearchAction .CREATE .value ,
257286 OpensearchAction .DELETE .value ,
258- OpensearchAction .REBUILD .value ,
259287 ],
260288 )
289+ subparser .add_argument ("--suffix" , type = str , default = None , help = "A suffix for the index name to create/delete (if you don't provide one, a timestamp will be used for creation)." )
261290 subparser .add_argument ("--force" , action = "store_true" , default = False , help = "Do not ask for confirmation." )
262291 subparser .add_argument ("--ignore-error" , action = "store_true" , default = False , help = "Do not stop on error." )
263292 subparser .add_argument (
@@ -279,7 +308,7 @@ def add_arguments(self, parser):
279308 subparser .add_argument (
280309 "action" ,
281310 type = str ,
282- help = "Whether you want to create , delete or rebuild the indices." ,
311+ help = "Whether you want to index , delete or update documents in indices." ,
283312 choices = [
284313 OpensearchAction .INDEX .value ,
285314 OpensearchAction .DELETE .value ,
@@ -316,6 +345,7 @@ def add_arguments(self, parser):
316345 ),
317346 )
318347 subparser .add_argument ("--force" , action = "store_true" , default = False , help = "Do not ask for confirmation." )
348+ subparser .add_argument ("--index-suffix" , type = str , default = None , help = "The suffix for the index name (if you don't provide one, the current index will be used)." )
319349 subparser .add_argument (
320350 "-i" , "--indices" , type = str , nargs = "*" , help = "Only update documents on the given indices."
321351 )
0 commit comments