diff --git a/milvus_cli/Cli.py b/milvus_cli/Cli.py index 2a228bb..273c4f2 100644 --- a/milvus_cli/Cli.py +++ b/milvus_cli/Cli.py @@ -1,19 +1,23 @@ from Connection import MilvusConnection from Database import MilvusDatabase +from Collection import MilvusCollection from pymilvus import __version__ from Types import ParameterException + def getPackageVersion(): import pkg_resources # part of setuptools + try: version = pkg_resources.require("milvus_cli")[0].version except Exception as e: raise ParameterException( - "Could not get version under single executable file mode.") + "Could not get version under single executable file mode." + ) return version -class MilvusCli(object): - connection = MilvusConnection() - database = MilvusDatabase() - +class MilvusCli(object): + connection = MilvusConnection() + database = MilvusDatabase() + collection = MilvusCollection() diff --git a/milvus_cli/Collection.py b/milvus_cli/Collection.py index 8398a0e..5b6fa3f 100644 --- a/milvus_cli/Collection.py +++ b/milvus_cli/Collection.py @@ -8,7 +8,7 @@ CollectionSchema, ) from tabulate import tabulate -from milvus_cli.Types import DataTypeByNum +from Types import DataTypeByNum class MilvusCollection(object): @@ -22,8 +22,8 @@ def create_collection( autoId=None, description=None, isDynamic=None, - consistencyLevel=None, - shardsNum=2, + consistencyLevel="Bounded", + shardsNum=1, alias=None, ): fieldList = [] diff --git a/milvus_cli/scripts/collection_cli.py b/milvus_cli/scripts/collection_cli.py new file mode 100644 index 0000000..e9e3450 --- /dev/null +++ b/milvus_cli/scripts/collection_cli.py @@ -0,0 +1,234 @@ +from tabulate import tabulate +from helper_cli import create, getList, delete, rename, show +import click +import os +import sys + +current_dir = os.path.dirname(os.path.realpath(__file__)) +parent_dir = os.path.dirname(current_dir) +sys.path.append(parent_dir) + +from Validation import validateCollectionParameter +from Types import ParameterException, ConnectException + + +@create.command("collection") +@click.option( + "-c", + "--collection-name", + "collectionName", + help="Collection name to specify alias.", + type=str, +) +@click.option( + "-p", "--schema-primary-field", "primaryField", help="Primary field name." +) +@click.option( + "-A", + "--schema-auto-id", + "autoId", + help="[Optional, Flag] - Enable auto id.", + default=False, + is_flag=True, +) +@click.option( + "-a", + "--alias", + "alias", + help="The connection alias name.", + type=str, +) +@click.option( + "-desc", + "--schema-description", + "description", + help="[Optional] - Description details.", + default="", +) +@click.option( + "-d", + "--is-dynamic", + "isDynamic", + help="[Optional] - Collection schema supports dynamic fields or not.", + default=None, +) +@click.option( + "-level", + "--consistency-level", + "consistencyLevel", + help="[Optional] - Consistency level: Bounded,Session,Strong, Eventual .", + default="Bounded", +) +@click.option( + "-f", + "--schema-field", + "fields", + help='[Multiple] - FieldSchema. Usage is "::"', + default=None, + multiple=True, +) +@click.option( + "-s", + "--shards-num", + "shardsNum", + help="[Optional] - Shards number", + default=1, + type=int, +) +@click.pass_obj +def create_collection( + obj, + collectionName, + primaryField, + autoId, + description, + fields, + isDynamic, + consistencyLevel, + shardsNum, + alias, +): + """ + Create collection. + + Example: + + create collection -c car -f id:INT64:primary_field -f vector:FLOAT_VECTOR:128 -f color:INT64:color -f brand:INT64:brand -p id -A -d 'car_collection' + """ + try: + validateCollectionParameter( + collectionName, + primaryField, + fields, + ) + except ParameterException as pe: + click.echo("Error!\n{}".format(str(pe))) + else: + click.echo( + obj.collection.create_collection( + collectionName, + primaryField, + fields, + autoId, + description, + isDynamic, + consistencyLevel, + shardsNum, + alias, + ) + ) + click.echo("Create collection successfully!") + + +@getList.command("collections") +@click.option( + "-a", + "--alias", + "alias", + help="The connection alias name.", + type=str, +) +@click.pass_obj +def collections(obj, alias): + """List all collections.""" + try: + click.echo(obj.collection.list_collections(alias)) + except Exception as e: + click.echo(message=e, err=True) + + +@delete.command("collection") +@click.option( + "-a", + "--alias", + "alias", + help="[Optional]: The connection alias name.", + type=str, +) +@click.option( + "-c", + "--collection-name", + "collectionName", + help="The name of collection to be deleted.", + required=True, +) +@click.pass_obj +def delete_collection(obj, collectionName, alias): + """ + Drops the collection together with its index files. + + Example: + + milvus_cli > delete collection -c car + """ + click.echo( + "Warning!\nYou are trying to delete the collection with data. This action cannot be undone!\n" + ) + if not click.confirm("Do you want to continue?"): + return + try: + obj.collection.has_collection(alias, collectionName) + except Exception as e: + click.echo(f"Error occurred when get collection by name!\n{str(e)}") + else: + result = obj.collection.drop_collection(alias, collectionName) + click.echo(result) + + +@rename.command("collection") +@click.option( + "-a", + "--alias", + "alias", + help="The connection alias name.", + type=str, +) +@click.option( + "-old", + "--old-collection-name", + "collectionName", + help="The old collection name", + type=str, + required=True, +) +@click.option( + "-new", + "--new-collection-name", + "newName", + help="The new collection name", + type=str, + required=True, +) +@click.pass_obj +def rename_collection(obj, alias, collectionName, newName): + """ + Rename collection. + + Example: + + milvus_cli > rename collection -old car -new new_car + """ + try: + obj.collection.has_collection(alias, collectionName) + except Exception as e: + click.echo(f"Error occurred when get collection by name!\n{str(e)}") + else: + result = obj.collection.rename_collection(alias, collectionName, newName) + click.echo(result) + + +@show.command("collection") +@click.option("-c", "--collection-name", "collection", help="The name of collection.") +@click.pass_obj +def describeCollection(obj, collection): + """ + Describe collection. + + Example: + + milvus_cli > describe collection -c test_collection_insert + """ + try: + click.echo(obj.collection.get_collection_details(collection)) + except Exception as e: + click.echo(message=e, err=True) diff --git a/milvus_cli/scripts/helper_cli.py b/milvus_cli/scripts/helper_cli.py index 2de1d46..f954035 100644 --- a/milvus_cli/scripts/helper_cli.py +++ b/milvus_cli/scripts/helper_cli.py @@ -37,7 +37,7 @@ def clear(): @cli.group(no_args_is_help=False) @click.pass_obj def show(obj): - """Show connection, database, loading_progress and index_progress.""" + """Show connection, database,collection, loading_progress and index_progress.""" pass @@ -48,6 +48,13 @@ def getList(obj): pass +@cli.group("rename", no_args_is_help=False) +@click.pass_obj +def rename(obj): + """Rename collection""" + pass + + @cli.group("create", no_args_is_help=False) @click.pass_obj def create(obj): diff --git a/milvus_cli/scripts/milvus_cli.py b/milvus_cli/scripts/milvus_cli.py index 571c939..a66be77 100644 --- a/milvus_cli/scripts/milvus_cli.py +++ b/milvus_cli/scripts/milvus_cli.py @@ -2,6 +2,7 @@ from connection_cli import connect, connection from helper_cli import help, version, clear, show, runCliPrompt from database_cli import create_database, list_databases, drop_database, use_database +from collection_cli import create_collection cli.add_command(help) cli.add_command(version) @@ -16,6 +17,8 @@ cli.add_command(drop_database) cli.add_command(use_database) +cli.add_command(create_collection) + if __name__ == "__main__": runCliPrompt() diff --git a/milvus_cli/scripts/old_milvus_cli.py b/milvus_cli/scripts/old_milvus_cli.py index 9205f32..8e14fe3 100644 --- a/milvus_cli/scripts/old_milvus_cli.py +++ b/milvus_cli/scripts/old_milvus_cli.py @@ -22,9 +22,7 @@ pass_context = click.make_pass_decorator(PyOrm, ensure=True) -@click.group(no_args_is_help=False, - add_help_option=False, - invoke_without_command=True) +@click.group(no_args_is_help=False, add_help_option=False, invoke_without_command=True) @click.pass_context def cli(ctx): """Milvus_CLI""" @@ -95,8 +93,7 @@ def help(): "-D", "--disconnect", "disconnect", - help= - "[Optional, Flag] - Disconnect from a Milvus server by alias, default is `default`.", + help="[Optional, Flag] - Disconnect from a Milvus server by alias, default is `default`.", default=False, is_flag=True, ) @@ -157,7 +154,8 @@ def connection(obj, showAll): except Exception as e: click.echo("No connections.") else: - click.echo(obj.showConnection(False,showAll=showAll)) + click.echo(obj.showConnection(False, showAll=showAll)) + @cli.group(no_args_is_help=False) @click.pass_obj @@ -165,6 +163,7 @@ def reset(obj): """Reset password.""" pass + @reset.command("password") @click.option( "-u", @@ -201,11 +200,11 @@ def resetPassword(obj, username, old_password, new_password): else: click.echo("Reset password successfully.") + @show.command("loading_progress") -@click.option("-c", - "--collection-name", - "collection", - help="The name of collection is loading") +@click.option( + "-c", "--collection-name", "collection", help="The name of collection is loading" +) @click.option( "-p", "--partition", @@ -219,52 +218,47 @@ def loadingProgress(obj, collection, partition): """Show #loaded entities vs #total entities.""" try: obj.checkConnection() - validateParamsByCustomFunc(obj.getTargetCollection, - "Collection Name Error!", collection) + validateParamsByCustomFunc( + obj.getTargetCollection, "Collection Name Error!", collection + ) result = obj.showCollectionLoadingProgress(collection, partition) except Exception as e: click.echo(message=e, err=True) else: click.echo( tabulate( - [[ - result.get("num_loaded_entities"), - result.get("num_total_entities") - ]], + [[result.get("num_loaded_entities"), result.get("num_total_entities")]], headers=["num_loaded_entities", "num_total_entities"], tablefmt="pretty", - )) + ) + ) @show.command("index_progress") -@click.option("-c", - "--collection-name", - "collection", - help="The name of collection is loading") +@click.option( + "-c", "--collection-name", "collection", help="The name of collection is loading" +) # ! TODO: To be removed -@click.option("-i", - "--index", - "index", - help="[Optional] - Index name.", - default="") +@click.option("-i", "--index", "index", help="[Optional] - Index name.", default="") @click.pass_obj def indexProgress(obj, collection, index): """Show # indexed entities vs. # total entities.""" try: obj.checkConnection() - validateParamsByCustomFunc(obj.getTargetCollection, - "Collection Name Error!", collection) + validateParamsByCustomFunc( + obj.getTargetCollection, "Collection Name Error!", collection + ) result = obj.showIndexBuildingProgress(collection, index) except Exception as e: click.echo(message=e, err=True) else: click.echo( tabulate( - [[result.get("indexed_rows"), - result.get("total_rows")]], + [[result.get("indexed_rows"), result.get("total_rows")]], headers=["indexed_rows", "total_rows"], tablefmt="pretty", - )) + ) + ) @show.command("query_segment") @@ -278,16 +272,14 @@ def indexProgress(obj, collection, index): "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. When timeout is not set, client waits until server response or error occur.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. When timeout is not set, client waits until server response or error occur.", default=None, type=float, ) @click.pass_obj def querySegmentInfo(obj, collection, timeout): """Return segments information from query nodes.""" - click.echo( - obj.getQuerySegmentInfo(collection, timeout, prettierFormat=True)) + click.echo(obj.getQuerySegmentInfo(collection, timeout, prettierFormat=True)) @show.command("compaction_state") @@ -301,8 +293,7 @@ def querySegmentInfo(obj, collection, timeout): "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. When timeout is not set, client waits until server response or error occur.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. When timeout is not set, client waits until server response or error occur.", default=None, type=float, ) @@ -323,8 +314,7 @@ def compactionStateInfo(obj, collection, timeout): "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. When timeout is not set, client waits until server response or error occur.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. When timeout is not set, client waits until server response or error occur.", default=None, type=float, ) @@ -335,10 +325,9 @@ def compactionStateInfo(obj, collection, timeout): @cli.command() -@click.option("-c", - "--collection-name", - "collection", - help="The name of collection to load.") +@click.option( + "-c", "--collection-name", "collection", help="The name of collection to load." +) @click.option( "-p", "--partition", @@ -351,8 +340,9 @@ def compactionStateInfo(obj, collection, timeout): def load(obj, collection, partition): """Load specified collection/partitions from disk to memory.""" try: - validateParamsByCustomFunc(obj.getTargetCollection, - "Collection Name Error!", collection) + validateParamsByCustomFunc( + obj.getTargetCollection, "Collection Name Error!", collection + ) for partitionName in partition: validateParamsByCustomFunc( obj.getTargetPartition, @@ -368,8 +358,7 @@ def load(obj, collection, partition): click.echo(message=e, err=True) else: if partition: - click.echo( - f"""Load {collection}'s partitions {partition} successfully""") + click.echo(f"""Load {collection}'s partitions {partition} successfully""") else: click.echo(f"""Load Collection {collection} successfully""") click.echo(result) @@ -394,8 +383,9 @@ def load(obj, collection, partition): def release(obj, collection, partition): """Release specified collection/partitions from memory.""" try: - validateParamsByCustomFunc(obj.getTargetCollection, - "Collection Name Error!", collection) + validateParamsByCustomFunc( + obj.getTargetCollection, "Collection Name Error!", collection + ) for partitionName in partition: validateParamsByCustomFunc( obj.getTargetPartition, @@ -451,8 +441,7 @@ def listDetails(obj): "--timeout", "-t", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. When timeout is not set, client waits until server response or error occur.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. When timeout is not set, client waits until server response or error occur.", default=None, type=float, ) @@ -467,34 +456,30 @@ def collections(obj, timeout): @listDetails.command() -@click.option("-c", - "--collection-name", - "collection", - help="The name of collection.") +@click.option("-c", "--collection-name", "collection", help="The name of collection.") @click.pass_obj def partitions(obj, collection): """List all partitions of the specified collection.""" try: obj.checkConnection() - validateParamsByCustomFunc(obj.getTargetCollection, - "Collection Name Error!", collection) + validateParamsByCustomFunc( + obj.getTargetCollection, "Collection Name Error!", collection + ) click.echo(obj.listPartitions(collection)) except Exception as e: click.echo(message=e, err=True) @listDetails.command() -@click.option("-c", - "--collection-name", - "collection", - help="The name of collection.") +@click.option("-c", "--collection-name", "collection", help="The name of collection.") @click.pass_obj def indexes(obj, collection): """List all indexes of the specified collection.""" try: obj.checkConnection() - validateParamsByCustomFunc(obj.getTargetCollection, - "Collection Name Error!", collection) + validateParamsByCustomFunc( + obj.getTargetCollection, "Collection Name Error!", collection + ) click.echo(obj.listIndexes(collection)) except Exception as e: click.echo(message=e, err=True) @@ -519,10 +504,7 @@ def describeDetails(obj): @describeDetails.command("collection") -@click.option("-c", - "--collection-name", - "collection", - help="The name of collection.") +@click.option("-c", "--collection-name", "collection", help="The name of collection.") @click.pass_obj def describeCollection(obj, collection): """ @@ -540,10 +522,9 @@ def describeCollection(obj, collection): @describeDetails.command("partition") -@click.option("-c", - "--collection-name", - "collectionName", - help="The name of collection.") +@click.option( + "-c", "--collection-name", "collectionName", help="The name of collection." +) @click.option( "-p", "--partition", @@ -570,10 +551,9 @@ def describePartition(obj, collectionName, partition): @describeDetails.command("index") -@click.option("-c", - "--collection-name", - "collectionName", - help="The name of collection.") +@click.option( + "-c", "--collection-name", "collectionName", help="The name of collection." +) @click.option("-in", "--index-name", "indexName", help="The name of index.") @click.pass_obj def describeIndex(obj, collectionName, indexName): @@ -628,8 +608,7 @@ def createDetails(obj): "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", default=None, type=float, ) @@ -651,11 +630,9 @@ def createAlias(obj, collectionName, aliasNames, alter, timeout): try: obj.checkConnection() if alter: - result = obj.alterCollectionAliasList(collectionName, aliasNames, - timeout) + result = obj.alterCollectionAliasList(collectionName, aliasNames, timeout) else: - result = obj.createCollectionAliasList(collectionName, aliasNames, - timeout) + result = obj.createCollectionAliasList(collectionName, aliasNames, timeout) except ConnectException as ce: click.echo("Error!\n{}".format(str(ce))) else: @@ -673,10 +650,9 @@ def createAlias(obj, collectionName, aliasNames, alter, timeout): help="Collection name to specify alias.", type=str, ) -@click.option("-p", - "--schema-primary-field", - "primaryField", - help="Primary field name.") +@click.option( + "-p", "--schema-primary-field", "primaryField", help="Primary field name." +) @click.option( "-a", "--schema-auto-id", @@ -696,14 +672,12 @@ def createAlias(obj, collectionName, aliasNames, alter, timeout): "-f", "--schema-field", "fields", - help= - '[Multiple] - FieldSchema. Usage is "::"', + help='[Multiple] - FieldSchema. Usage is "::"', default=None, multiple=True, ) @click.pass_obj -def createCollection(obj, collectionName, primaryField, autoId, description, - fields): +def createCollection(obj, collectionName, primaryField, autoId, description, fields): """ Create collection. @@ -720,16 +694,15 @@ def createCollection(obj, collectionName, primaryField, autoId, description, click.echo("Error!\n{}".format(str(ce))) else: click.echo( - obj.createCollection(collectionName, primaryField, autoId, - description, fields)) + obj.createCollection( + collectionName, primaryField, autoId, description, fields + ) + ) click.echo("Create collection successfully!") @createDetails.command("partition") -@click.option("-c", - "--collection-name", - "collectionName", - help="Collection name.") +@click.option("-c", "--collection-name", "collectionName", help="Collection name.") @click.option("-p", "--partition", "partition", help="The name of partition.") @click.option( "-d", @@ -781,21 +754,22 @@ def createIndex(obj): """ try: obj.checkConnection() - collectionName = click.prompt("Collection name", - type=click.Choice( - obj._list_collection_names())) + collectionName = click.prompt( + "Collection name", type=click.Choice(obj._list_collection_names()) + ) fieldName = click.prompt( "The name of the field to create an index for", type=click.Choice( - obj._list_field_names(collectionName, showVectorOnly=True)), + obj._list_field_names(collectionName, showVectorOnly=True) + ), ) indexName = click.prompt("Index name") indexType = click.prompt("Index type", type=click.Choice(IndexTypes)) - metricType = click.prompt("Index metric type", - type=click.Choice(MetricTypes)) + metricType = click.prompt("Index metric type", type=click.Choice(MetricTypes)) index_building_parameters = IndexTypesMap[indexType][ - "index_building_parameters"] + "index_building_parameters" + ] params = [] for param in index_building_parameters: tmpParam = click.prompt(f"Index params {param}") @@ -809,20 +783,22 @@ def createIndex(obj): click.echo("Error!\n{}".format(str(ce))) else: click.echo( - obj.createIndex(collectionName, fieldName, indexName, indexType, - metricType, params, timeout)) + obj.createIndex( + collectionName, + fieldName, + indexName, + indexType, + metricType, + params, + timeout, + ) + ) click.echo("Create index successfully!") @createDetails.command("user") -@click.option("-u", - "--username", - "username", - help="The username of milvus user.") -@click.option("-p", - "--password", - "password", - help="The pawssord of milvus user.") +@click.option("-u", "--username", "username", help="The username of milvus user.") +@click.option("-p", "--password", "password", help="The pawssord of milvus user.") @click.pass_obj def createUser(obj, username, password): """ @@ -848,17 +824,14 @@ def deleteObject(obj): @deleteObject.command("alias") -@click.option("-a", - "--alias-name", - "aliasName", - help="The alias of the collection.", - type=str) +@click.option( + "-a", "--alias-name", "aliasName", help="The alias of the collection.", type=str +) @click.option( "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", default=None, type=float, ) @@ -892,8 +865,7 @@ def deleteAlias(obj, aliasName, timeout): "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", default=None, type=float, ) @@ -912,28 +884,24 @@ def deleteCollection(obj, collectionName, timeout): if not click.confirm("Do you want to continue?"): return try: - obj.checkConnection() obj.getTargetCollection(collectionName) except Exception as e: click.echo(f"Error occurred when get collection by name!\n{str(e)}") else: result = obj.dropCollection(collectionName, timeout) - click.echo("Drop collection successfully!" - ) if not result else click.echo("Drop collection failed!") + click.echo("Drop collection successfully!") if not result else click.echo( + "Drop collection failed!" + ) @deleteObject.command("partition") -@click.option("-c", - "--collection-name", - "collectionName", - help="Collection name") +@click.option("-c", "--collection-name", "collectionName", help="Collection name") @click.option("-p", "--partition", "partition", help="The name of partition.") @click.option( "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", default=None, type=float, ) @@ -958,22 +926,19 @@ def deletePartition(obj, collectionName, partition, timeout): click.echo(f"Error occurred when get collection by name!\n{str(e)}") else: result = obj.dropPartition(collectionName, partition, timeout) - click.echo("Drop partition successfully!" - ) if not result else click.echo("Drop partition failed!") + click.echo("Drop partition successfully!") if not result else click.echo( + "Drop partition failed!" + ) @deleteObject.command("index") -@click.option("-c", - "--collection-name", - "collectionName", - help="Collection name") +@click.option("-c", "--collection-name", "collectionName", help="Collection name") @click.option("-in", "--index-name", "indexName", help="Index name") @click.option( "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", default=None, type=float, ) @@ -1002,10 +967,7 @@ def deleteIndex(obj, collectionName, indexName, timeout): @deleteObject.command("user") -@click.option("-u", - "--username", - "username", - help="The username of milvus user") +@click.option("-u", "--username", "username", help="The username of milvus user") @click.pass_obj def deleteUser(obj, username): """ @@ -1030,10 +992,7 @@ def deleteUser(obj, username): @deleteObject.command("entities") -@click.option("-c", - "--collection-name", - "collectionName", - help="Collection name.") +@click.option("-c", "--collection-name", "collectionName", help="Collection name.") @click.option( "-p", "--partition", @@ -1045,8 +1004,7 @@ def deleteUser(obj, username): "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", default=None, type=float, ) @@ -1081,8 +1039,7 @@ def deleteEntities(obj, collectionName, partitionName, timeout): else: partitionValue = partitionName if partitionName else None timeoutValue = timeout if timeout else None - result = obj.deleteEntities(expr, collectionName, partitionValue, - timeoutValue) + result = obj.deleteEntities(expr, collectionName, partitionValue, timeoutValue) click.echo(result) @@ -1169,16 +1126,15 @@ def search(obj): Timeout []: """ - collectionName = click.prompt("Collection name", - type=click.Choice( - obj._list_collection_names())) + collectionName = click.prompt( + "Collection name", type=click.Choice(obj._list_collection_names()) + ) data = click.prompt( "The vectors of search data (the length of data is number of query (nq), the dim of every vector in data must be equal to vector field’s of collection. You can also import a CSV file without headers)" ) annsField = click.prompt( "The vector field used to search of collection", - type=click.Choice( - obj._list_field_names(collectionName, showVectorOnly=True)), + type=click.Choice(obj._list_field_names(collectionName, showVectorOnly=True)), ) indexDetails = obj._list_index(collectionName) hasIndex = not not indexDetails @@ -1201,11 +1157,9 @@ def search(obj): type=int, ) limit = click.prompt( - "The max number of returned record, also known as topk", - default=None, - type=int) - expr = click.prompt("The boolean expression used to filter attribute", - default="") + "The max number of returned record, also known as topk", default=None, type=int + ) + expr = click.prompt("The boolean expression used to filter attribute", default="") partitionNames = click.prompt( f'The names of partitions to search (split by "," if multiple) {obj._list_partition_names(collectionName)}', default="", @@ -1250,9 +1204,7 @@ def search(obj): click.echo("Error!\n{}".format(str(ce))) else: if export: - results = obj.search(collectionName, - searchParameters, - prettierFormat=False) + results = obj.search(collectionName, searchParameters, prettierFormat=False) else: results = obj.search(collectionName, searchParameters) click.echo(f"Search results:\n") @@ -1307,9 +1259,9 @@ def query(obj): Travel timestamp. Users can specify a timestamp in a search to get results based on a data view at a specified point in time. [0]: 428960801420883491 """ - collectionName = click.prompt("Collection name", - type=click.Choice( - obj._list_collection_names())) + collectionName = click.prompt( + "Collection name", type=click.Choice(obj._list_collection_names()) + ) expr = click.prompt("The query expression") partitionNames = click.prompt( f'The names of partitions to search (split by "," if multiple) {obj._list_partition_names(collectionName)}', @@ -1365,16 +1317,14 @@ def query(obj): "-p", "--partition", "partitionName", - help= - "[Optional] - The partition name which the data will be inserted to, if partition name is not passed, then the data will be inserted to “_default” partition.", + help="[Optional] - The partition name which the data will be inserted to, if partition name is not passed, then the data will be inserted to “_default” partition.", default=None, ) @click.option( "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", default=None, type=float, ) @@ -1432,8 +1382,9 @@ def importData(obj, collectionName, partitionName, timeout, path): """ try: obj.checkConnection() - validateParamsByCustomFunc(obj.getTargetCollection, - "Collection Name Error!", collectionName) + validateParamsByCustomFunc( + obj.getTargetCollection, "Collection Name Error!", collectionName + ) result = readCsvFile(path.replace('"', "").replace("'", "")) data = result["data"] result = obj.importData(collectionName, data, partitionName, timeout) @@ -1524,11 +1475,12 @@ def calcDistance(obj): if click.confirm("Import left operator vectors from existing collection?"): left_ids = click.prompt("The vectors' ids on the left of operator") left_collection = click.prompt( - "The vectors' collection name on the left of operator") + "The vectors' collection name on the left of operator" + ) left_partition = click.prompt( - "The vectors' partition name on the left of operator") - left_field = click.prompt( - "The vectors' field name on the left of operator") + "The vectors' partition name on the left of operator" + ) + left_field = click.prompt("The vectors' field name on the left of operator") leftVectorMeta["vec_type"] = "import" leftVectorMeta["ids"] = left_ids leftVectorMeta["collection"] = left_collection @@ -1545,15 +1497,15 @@ def calcDistance(obj): leftVectorMeta["type"] = left_type leftVectorMeta["vectors"] = left_vectors rightVectorMeta = {} - if click.confirm( - "Import right operator vectors from existing collection?"): + if click.confirm("Import right operator vectors from existing collection?"): right_ids = click.prompt("The vectors' ids on the right of operator") right_collection = click.prompt( - "The vectors' collection name on the right of operator") + "The vectors' collection name on the right of operator" + ) right_partition = click.prompt( - "The vectors' partition name on the right of operator") - right_field = click.prompt( - "The vectors' field name on the right of operator") + "The vectors' partition name on the right of operator" + ) + right_field = click.prompt("The vectors' field name on the right of operator") rightVectorMeta["vec_type"] = "import" rightVectorMeta["ids"] = right_ids rightVectorMeta["collection"] = right_collection @@ -1586,8 +1538,9 @@ def calcDistance(obj): ) timeout = click.prompt("Timeout(optional)", default="") try: - calcParams = validateCalcParams(leftVectorMeta, rightVectorMeta, - metric_type, sqrt, dim, timeout) + calcParams = validateCalcParams( + leftVectorMeta, rightVectorMeta, metric_type, sqrt, dim, timeout + ) result = obj.calcDistance( calcParams["vectors_left"], calcParams["vectors_right"], @@ -1600,15 +1553,17 @@ def calcDistance(obj): click.echo("Error!\n{}".format(str(ce))) else: click.echo( - "\n======\nReturn type:\n" + - "Assume the vectors_left: L_1, L_2, L_3\n" + - "Assume the vectors_right: R_a, R_b\n" + - 'Distance between L_n and R_m we called "D_n_m"\n' + - "The returned distances are arranged like this:\n" + - " [[D_1_a, D_1_b],\n" + " [D_2_a, D_2_b],\n" + - " [D_3_a, D_3_b]]\n" + - '\nNote: if some vectors doesn\'t exist in collection, the returned distance is "-1.0"\n' - + "======\n") + "\n======\nReturn type:\n" + + "Assume the vectors_left: L_1, L_2, L_3\n" + + "Assume the vectors_right: R_a, R_b\n" + + 'Distance between L_n and R_m we called "D_n_m"\n' + + "The returned distances are arranged like this:\n" + + " [[D_1_a, D_1_b],\n" + + " [D_2_a, D_2_b],\n" + + " [D_3_a, D_3_b]]\n" + + '\nNote: if some vectors doesn\'t exist in collection, the returned distance is "-1.0"\n' + + "======\n" + ) click.echo("Result:\n") click.echo(result) @@ -1618,8 +1573,7 @@ def calcDistance(obj): "-h", "--hybridts", "hybridts", - help= - "The original hybrid timestamp used to generate a new hybrid timestamp. Non-negative interger range from 0 to 18446744073709551615.", + help="The original hybrid timestamp used to generate a new hybrid timestamp. Non-negative interger range from 0 to 18446744073709551615.", type=int, ) @click.option( @@ -1648,8 +1602,7 @@ def hybridts2mkts(obj, hybridts, milliseconds): "-e", "--epoch", "epoch", - help= - "The known Unix Epoch time used to generate a hybrid timestamp. The Unix Epoch time is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT).", + help="The known Unix Epoch time used to generate a hybrid timestamp. The Unix Epoch time is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT).", type=float, ) @click.option( @@ -1672,8 +1625,7 @@ def unixtime2mkts(obj, epoch, milliseconds): "-h", "--hybridts", "hybridts", - help= - "The known hybrid timestamp to convert to UNIX Epoch time. Non-negative interger range from 0 to 18446744073709551615.", + help="The known hybrid timestamp to convert to UNIX Epoch time. Non-negative interger range from 0 to 18446744073709551615.", type=int, ) @click.pass_obj @@ -1717,22 +1669,17 @@ def hybridts2unixtime(obj, hybridts): @click.pass_obj def loadBalance(obj, src_node_id, dst_node_ids, sealed_segment_ids, timeout): """Do load balancing operation from source query node to destination query node.""" - res = obj.loadBalance(src_node_id, dst_node_ids, sealed_segment_ids, - timeout) + res = obj.loadBalance(src_node_id, dst_node_ids, sealed_segment_ids, timeout) click.echo(res) @cli.command("compact") -@click.option("-c", - "--collection-name", - "collectionName", - help="Collection name") +@click.option("-c", "--collection-name", "collectionName", help="Collection name") @click.option( "-t", "--timeout", "timeout", - help= - "[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", + help="[Optional] - An optional duration of time in seconds to allow for the RPC. If timeout is not set, the client keeps waiting until the server responds or an error occurs.", default=None, type=float, ) @@ -1777,8 +1724,7 @@ def runCliPrompt(): click.echo(message=f"{str(pe)}", err=True) except ConnectException as ce: click.echo( - message= - "Connect to milvus Error!\nPlease check your connection.", + message="Connect to milvus Error!\nPlease check your connection.", err=True, ) except Exception as e: diff --git a/milvus_cli/utils.py b/milvus_cli/utils.py index cbb584d..52124b2 100644 --- a/milvus_cli/utils.py +++ b/milvus_cli/utils.py @@ -692,7 +692,11 @@ class Completer(object): "query_segment", "compaction_state", "compaction_plans", + "collection", + "partition", + "index", ], + "rename": ["collection"], "version": [], }