diff --git a/arango/collection.py b/arango/collection.py index fec5266b..930ef771 100644 --- a/arango/collection.py +++ b/arango/collection.py @@ -9,7 +9,9 @@ from arango.exceptions import ( ArangoServerError, CollectionChecksumError, + CollectionCompactError, CollectionConfigureError, + CollectionInformationError, CollectionLoadError, CollectionPropertiesError, CollectionRecalculateCountError, @@ -335,6 +337,26 @@ def response_handler(resp: Response) -> Json: return self._execute(request, response_handler) + def info(self) -> Result[Json]: + """Return the collection information. + + :return: Information about the collection. + :rtype: dict + :raise arango.exceptions.CollectionInformationError: If retrieval fails. + """ + request = Request( + method="get", + endpoint=f"/_api/collection/{self.name}", + read=self.name, + ) + + def response_handler(resp: Response) -> Json: + if resp.is_success: + return format_collection(resp.body) + raise CollectionInformationError(resp, request) + + return self._execute(request, response_handler) + def configure( self, sync: Optional[bool] = None, @@ -480,6 +502,35 @@ def response_handler(resp: Response) -> str: return self._execute(request, response_handler) + def compact(self) -> Result[Json]: + """Compact a collection. + + Compacts the data of a collection in order to reclaim disk space. + The operation will compact the document and index data by rewriting the + underlying .sst files and only keeping the relevant entries. + + Under normal circumstances, running a compact operation is not necessary, as + the collection data will eventually get compacted anyway. However, in some + situations, e.g. after running lots of update/replace or remove operations, + the disk data for a collection may contain a lot of outdated data for which the + space shall be reclaimed. In this case the compaction operation can be used. + + :return: Collection compact. + :rtype: dict + :raise arango.exceptions.CollectionCompactError: If retrieval fails. + """ + request = Request( + method="put", + endpoint=f"/_api/collection/{self.name}/compact", + ) + + def response_handler(resp: Response) -> Json: + if resp.is_success: + return format_collection(resp.body) + raise CollectionCompactError(resp, request) + + return self._execute(request, response_handler) + def load(self) -> Result[bool]: """Load the collection into memory. diff --git a/arango/exceptions.py b/arango/exceptions.py index f9b6de2d..954fd38a 100644 --- a/arango/exceptions.py +++ b/arango/exceptions.py @@ -250,6 +250,10 @@ class CollectionListError(ArangoServerError): """Failed to retrieve collections.""" +class CollectionInformationError(ArangoServerError): + """Failed to retrieve collection information.""" + + class CollectionPropertiesError(ArangoServerError): """Failed to retrieve collection properties.""" @@ -274,6 +278,10 @@ class CollectionChecksumError(ArangoServerError): """Failed to retrieve collection checksum.""" +class CollectionCompactError(ArangoServerError): + """Failed to compact collection.""" + + class CollectionCreateError(ArangoServerError): """Failed to create collection.""" diff --git a/tests/test_collection.py b/tests/test_collection.py index 10239a23..a2d07587 100644 --- a/tests/test_collection.py +++ b/tests/test_collection.py @@ -151,6 +151,16 @@ def test_collection_misc_methods(col, bad_col, cluster): bad_col.recalculate_count() assert err.value.error_code in {11, 1228} + # Test collection info + info = col.info() + assert set(info.keys()) == {"id", "name", "system", "type", "status", "global_id"} + assert info["name"] == col.name + assert info["system"] is False + + # Test collection compact + result = col.compact() + assert result == info + def test_collection_management(db, bad_db, cluster): # Test create collection