diff --git a/README.md b/README.md index 8b7a12dd..233e6660 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ # Python Qdrant Client -Client library and SDK for the [Qdrant](https://github.com/qdrant/qdrant) vector search engine. +Client library and SDK for the [Qdrant](https://github.com/qdrant/qdrant) vector search engine. Library contains type definitions for all Qdrant API and allows to make both Sync and Async requests. @@ -171,7 +171,7 @@ Create a new collection ```python from qdrant_client.models import Distance, VectorParams -client.recreate_collection( +client.create_collection( collection_name="my_collection", vectors_config=VectorParams(size=100, distance=Distance.COSINE), ) diff --git a/docs/source/index.rst b/docs/source/index.rst index f82630b8..1a5517e3 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -36,10 +36,11 @@ Create a new collection from qdrant_client.models import VectorParams, Distance - client.recreate_collection( - collection_name="my_collection", - vectors_config=VectorParams(size=100, distance=Distance.COSINE), - ) + if not client.collection_exists("my_collection"): + client.create_collection( + collection_name="my_collection", + vectors_config=VectorParams(size=100, distance=Distance.COSINE), + ) Insert vectors into a collection @@ -109,10 +110,11 @@ Starting from version 1.6.1, all python client methods are available in async ve # Your async code using QdrantClient might be put here client = AsyncQdrantClient(url="http://localhost:6333") - await client.create_collection( - collection_name="my_collection", - vectors_config=models.VectorParams(size=10, distance=models.Distance.COSINE), - ) + if not await client.collection_exists("my_collection"): + await client.create_collection( + collection_name="my_collection", + vectors_config=models.VectorParams(size=10, distance=models.Distance.COSINE), + ) await client.upsert( collection_name="my_collection", @@ -172,10 +174,9 @@ Indices and tables QdrantClient AsyncQdrantClient FastEmbed Mixin - + .. toctree:: :maxdepth: 1 :caption: Complete Docs Complete Client API Docs - diff --git a/docs/source/quickstart.ipynb b/docs/source/quickstart.ipynb index 468ba93d..17dcf19d 100644 --- a/docs/source/quickstart.ipynb +++ b/docs/source/quickstart.ipynb @@ -209,10 +209,11 @@ "source": [ "from qdrant_client.http.models import Distance, VectorParams\n", "\n", - "client.create_collection(\n", - " collection_name=\"test_collection\",\n", - " vectors_config=VectorParams(size=4, distance=Distance.DOT),\n", - ")" + "if not client.collection_exists(\"test_collection\"):\n", + "\tclient.create_collection(\n", + "\t\tcollection_name=\"test_collection\",\n", + "\t\tvectors_config=VectorParams(size=4, distance=Distance.DOT),\n", + "\t)" ] }, { diff --git a/qdrant_client/local/local_collection.py b/qdrant_client/local/local_collection.py index d4f3980b..87c1e2cc 100644 --- a/qdrant_client/local/local_collection.py +++ b/qdrant_client/local/local_collection.py @@ -2310,6 +2310,7 @@ def ignore_mentioned_ids_filter( if query_filter is None: query_filter = models.Filter(must_not=[ignore_mentioned_ids]) else: + # as of mypy v1.11.0 mypy is complaining on deep-copied structures with None query_filter = deepcopy(query_filter) # as of mypy v1.11.0 mypy is complaining on deep-copied structures with None if query_filter.must_not is None: # type: ignore[union-attr] @@ -2331,6 +2332,7 @@ def _include_ids_in_filter( if query_filter is None: query_filter = models.Filter(must=[include_ids]) else: + # as of mypy v1.11.0 mypy is complaining on deep-copied structures with None query_filter = deepcopy(query_filter) # as of mypy v1.11.0 mypy is complaining on deep-copied structures with None if query_filter.must is None: # type: ignore[union-attr] diff --git a/qdrant_client/migrate/migrate.py b/qdrant_client/migrate/migrate.py index 0573adbe..7e23eb16 100644 --- a/qdrant_client/migrate/migrate.py +++ b/qdrant_client/migrate/migrate.py @@ -111,8 +111,9 @@ def _recreate_collection( src_collection_info = source_client.get_collection(collection_name) src_config = src_collection_info.config src_payload_schema = src_collection_info.payload_schema - - dest_client.recreate_collection( + if dest_client.collection_exists(collection_name): + dest_client.delete_collection(collection_name) + dest_client.create_collection( collection_name, vectors_config=src_config.params.vectors, sparse_vectors_config=src_config.params.sparse_vectors, diff --git a/tests/benches/test_grpc_upload.py b/tests/benches/test_grpc_upload.py index 076290a2..99b8d3a2 100644 --- a/tests/benches/test_grpc_upload.py +++ b/tests/benches/test_grpc_upload.py @@ -17,8 +17,11 @@ def get_data(num_vectors: int): def prepare_collection_rest(): client = QdrantClient(timeout=30) - client.recreate_collection( - COLLECTION_NAME, vectors_config=VectorParams(size=VECTOR_SIZE, distance=Distance.COSINE) + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(COLLECTION_NAME) + client.create_collection( + COLLECTION_NAME, + vectors_config=VectorParams(size=VECTOR_SIZE, distance=Distance.COSINE), ) diff --git a/tests/benches/test_rest_upload.py b/tests/benches/test_rest_upload.py index 0c038bed..585ca46e 100644 --- a/tests/benches/test_rest_upload.py +++ b/tests/benches/test_rest_upload.py @@ -17,8 +17,11 @@ def get_data(num_vectors: int): def prepare_collection_rest(): client = QdrantClient(timeout=30) - client.recreate_collection( - COLLECTION_NAME, vectors_config=VectorParams(size=VECTOR_SIZE, distance=Distance.COSINE) + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(COLLECTION_NAME) + client.create_collection( + COLLECTION_NAME, + vectors_config=VectorParams(size=VECTOR_SIZE, distance=Distance.COSINE), ) diff --git a/tests/congruence_tests/test_collections.py b/tests/congruence_tests/test_collections.py index f0fdd8e3..2bc90096 100644 --- a/tests/congruence_tests/test_collections.py +++ b/tests/congruence_tests/test_collections.py @@ -1,9 +1,8 @@ from time import sleep from typing import Callable -import pytest - from qdrant_client.http import models +from qdrant_client.http.exceptions import UnexpectedResponse from tests.congruence_tests.test_common import ( compare_collections, generate_fixtures, @@ -12,6 +11,7 @@ from tests.congruence_tests.test_common import ( init_remote, ) + COLLECTION_NAME = "test_collection" @@ -52,6 +52,25 @@ def test_get_collection(): ) +def test_recreate_collection(): + # this method has been marked as deprecated and should be removed in qdrant-client v1.12 + local_client = init_local() + http_client = init_remote() + grpc_client = init_remote(prefer_grpc=True) + + vector_params = models.VectorParams(size=20, distance=models.Distance.COSINE) + + local_client.recreate_collection(COLLECTION_NAME, vectors_config=vector_params) + http_client.recreate_collection(COLLECTION_NAME, vectors_config=vector_params) + + assert local_client.collection_exists(COLLECTION_NAME) + assert http_client.collection_exists(COLLECTION_NAME) + + http_client.delete_collection(COLLECTION_NAME) + grpc_client.recreate_collection(COLLECTION_NAME, vectors_config=vector_params) + assert grpc_client.collection_exists(COLLECTION_NAME) + + def test_collection_exists(): remote_client = init_remote() local_client = init_local() @@ -61,8 +80,19 @@ def test_collection_exists(): vector_params = models.VectorParams(size=2, distance=models.Distance.COSINE) - remote_client.recreate_collection(COLLECTION_NAME, vectors_config=vector_params) - local_client.recreate_collection(COLLECTION_NAME, vectors_config=vector_params) + try: + remote_client.delete_collection(COLLECTION_NAME) + except UnexpectedResponse: + pass # collection does not exist + + remote_client.create_collection(COLLECTION_NAME, vectors_config=vector_params) + + try: + local_client.delete_collection(COLLECTION_NAME) + except ValueError: + pass # collection does not exist + + local_client.create_collection(COLLECTION_NAME, vectors_config=vector_params) assert remote_client.collection_exists(COLLECTION_NAME) assert local_client.collection_exists(COLLECTION_NAME) @@ -77,19 +107,28 @@ def test_init_from(): points = generate_fixtures(vectors_sizes=vector_size) vector_params = models.VectorParams(size=vector_size, distance=models.Distance.COSINE) - remote_client.recreate_collection( - collection_name=COLLECTION_NAME, vectors_config=vector_params - ) - local_client.recreate_collection(collection_name=COLLECTION_NAME, vectors_config=vector_params) + if remote_client.collection_exists(COLLECTION_NAME): + remote_client.delete_collection(collection_name=COLLECTION_NAME) + remote_client.create_collection(collection_name=COLLECTION_NAME, vectors_config=vector_params) + + if local_client.collection_exists(COLLECTION_NAME): + local_client.delete_collection(collection_name=COLLECTION_NAME) + local_client.create_collection(collection_name=COLLECTION_NAME, vectors_config=vector_params) + remote_client.upload_points(COLLECTION_NAME, points, wait=True) local_client.upload_points(COLLECTION_NAME, points) compare_collections(remote_client, local_client, len(points), collection_name=COLLECTION_NAME) new_collection_name = COLLECTION_NAME + "_new" - remote_client.recreate_collection( + if remote_client.collection_exists(new_collection_name): + remote_client.delete_collection(new_collection_name) + remote_client.create_collection( new_collection_name, vectors_config=vector_params, init_from=COLLECTION_NAME ) - local_client.recreate_collection( + + if local_client.collection_exists(new_collection_name): + local_client.delete_collection(new_collection_name) + local_client.create_collection( new_collection_name, vectors_config=vector_params, init_from=COLLECTION_NAME ) @@ -102,12 +141,17 @@ def test_init_from(): collection_name=new_collection_name, ) - remote_client.recreate_collection( + # try with models.InitFrom + if remote_client.collection_exists(new_collection_name): + remote_client.delete_collection(new_collection_name) + remote_client.create_collection( new_collection_name, vectors_config=vector_params, init_from=models.InitFrom(collection=COLLECTION_NAME), ) - local_client.recreate_collection( + if local_client.collection_exists(new_collection_name): + local_client.delete_collection(new_collection_name) + local_client.create_collection( new_collection_name, vectors_config=vector_params, init_from=models.InitFrom(collection=COLLECTION_NAME), diff --git a/tests/congruence_tests/test_common.py b/tests/congruence_tests/test_common.py index e97c591a..419ec2e3 100644 --- a/tests/congruence_tests/test_common.py +++ b/tests/congruence_tests/test_common.py @@ -99,7 +99,9 @@ def initialize_fixture_collection( if vectors_config is None: vectors_config = dense_vectors_config # no sparse vector config generated by default - client.recreate_collection( + if client.collection_exists(collection_name): + client.delete_collection(collection_name=collection_name, timeout=TIMEOUT) + client.create_collection( collection_name=collection_name, vectors_config=vectors_config, timeout=TIMEOUT, @@ -108,7 +110,8 @@ def initialize_fixture_collection( def delete_fixture_collection(client: QdrantBase) -> None: - client.delete_collection(COLLECTION_NAME) + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(COLLECTION_NAME) def generate_fixtures( diff --git a/tests/congruence_tests/test_payload.py b/tests/congruence_tests/test_payload.py index 88a44217..cf2b363f 100644 --- a/tests/congruence_tests/test_payload.py +++ b/tests/congruence_tests/test_payload.py @@ -1,7 +1,13 @@ +import datetime +import random +import uuid + +import numpy as np import pytest from qdrant_client import QdrantClient from qdrant_client.http import models +from qdrant_client.http.models import PointStruct from qdrant_client.http.exceptions import UnexpectedResponse from tests.congruence_tests.test_common import ( COLLECTION_NAME, @@ -148,20 +154,19 @@ def test_update_payload(local_client: QdrantClient, remote_client: QdrantClient) def test_not_jsonable_payload(): - import datetime - import random - import uuid - local_client = init_local() remote_client = init_remote() vector_size = 2 vectors_config = models.VectorParams(size=vector_size, distance=models.Distance.COSINE) - local_client.recreate_collection( + + local_client.create_collection( collection_name=COLLECTION_NAME, vectors_config=vectors_config, ) - remote_client.recreate_collection( + if remote_client.collection_exists(COLLECTION_NAME): + remote_client.delete_collection(collection_name=COLLECTION_NAME) + remote_client.create_collection( collection_name=COLLECTION_NAME, vectors_config=vectors_config, ) @@ -191,11 +196,13 @@ def test_not_jsonable_payload(): compare_collections(local_client, remote_client, len(points)) - local_client.recreate_collection( + local_client.delete_collection(collection_name=COLLECTION_NAME) + local_client.create_collection( collection_name=COLLECTION_NAME, vectors_config=vectors_config, ) - remote_client.recreate_collection( + remote_client.delete_collection(collection_name=COLLECTION_NAME) + remote_client.create_collection( collection_name=COLLECTION_NAME, vectors_config=vectors_config, ) @@ -237,21 +244,19 @@ def test_not_jsonable_payload(): def test_set_payload_with_key(): - import numpy as np - - from qdrant_client.models import PointStruct - local_client = init_local() remote_client = init_remote() vector_size = 2 vectors_config = models.VectorParams(size=vector_size, distance=models.Distance.COSINE) - local_client.recreate_collection( + local_client.create_collection( collection_name=COLLECTION_NAME, vectors_config=vectors_config, ) - remote_client.recreate_collection( + if remote_client.collection_exists(COLLECTION_NAME): + remote_client.delete_collection(collection_name=COLLECTION_NAME) + remote_client.create_collection( collection_name=COLLECTION_NAME, vectors_config=vectors_config, ) diff --git a/tests/congruence_tests/test_query.py b/tests/congruence_tests/test_query.py index cb8db9bb..eda9d72c 100644 --- a/tests/congruence_tests/test_query.py +++ b/tests/congruence_tests/test_query.py @@ -1273,8 +1273,13 @@ def test_query_with_nan(): single_vector_config = models.VectorParams( size=text_vector_size, distance=models.Distance.COSINE ) - local_client.recreate_collection(COLLECTION_NAME, vectors_config=single_vector_config) - http_client.recreate_collection(COLLECTION_NAME, vectors_config=single_vector_config) + + local_client.delete_collection(COLLECTION_NAME) + local_client.create_collection(COLLECTION_NAME, vectors_config=single_vector_config) + + http_client.delete_collection(COLLECTION_NAME) + http_client.create_collection(COLLECTION_NAME, vectors_config=single_vector_config) + fixture_points = generate_fixtures(vectors_sizes=text_vector_size) init_client(local_client, fixture_points, vectors_config=single_vector_config) init_client(http_client, fixture_points, vectors_config=single_vector_config) diff --git a/tests/congruence_tests/test_search.py b/tests/congruence_tests/test_search.py index 3a1f83f8..a015614c 100644 --- a/tests/congruence_tests/test_search.py +++ b/tests/congruence_tests/test_search.py @@ -359,8 +359,13 @@ def test_query_with_nan(): single_vector_config = models.VectorParams( size=text_vector_size, distance=models.Distance.COSINE ) - local_client.recreate_collection(COLLECTION_NAME, vectors_config=single_vector_config) - remote_client.recreate_collection(COLLECTION_NAME, vectors_config=single_vector_config) + + local_client.delete_collection(COLLECTION_NAME) + local_client.create_collection(COLLECTION_NAME, vectors_config=single_vector_config) + + remote_client.delete_collection(COLLECTION_NAME) + remote_client.create_collection(COLLECTION_NAME, vectors_config=single_vector_config) + fixture_points = generate_fixtures(vectors_sizes=text_vector_size) init_client(local_client, fixture_points, vectors_config=single_vector_config) init_client(remote_client, fixture_points, vectors_config=single_vector_config) diff --git a/tests/congruence_tests/test_sparse_search.py b/tests/congruence_tests/test_sparse_search.py index 85dbd659..53c5d3e3 100644 --- a/tests/congruence_tests/test_sparse_search.py +++ b/tests/congruence_tests/test_sparse_search.py @@ -297,10 +297,12 @@ def test_query_with_nan(): ) named_sparse_vector.vector.values[0] = np.nan - local_client.recreate_collection( + local_client.create_collection( COLLECTION_NAME, vectors_config={}, sparse_vectors_config=sparse_vectors_config ) - remote_client.recreate_collection( + if remote_client.collection_exists(COLLECTION_NAME): + remote_client.delete_collection(COLLECTION_NAME) + remote_client.create_collection( COLLECTION_NAME, vectors_config={}, sparse_vectors_config=sparse_vectors_config ) init_client( diff --git a/tests/congruence_tests/test_updates.py b/tests/congruence_tests/test_updates.py index 573d2417..1896eb1b 100644 --- a/tests/congruence_tests/test_updates.py +++ b/tests/congruence_tests/test_updates.py @@ -1,5 +1,4 @@ import itertools -import math import uuid from collections import defaultdict from typing import Dict, List @@ -158,10 +157,11 @@ def test_upload_collection_float_list(): vectors = np.random.randn(UPLOAD_NUM_VECTORS, vectors_dim).tolist() vectors_config = models.VectorParams(size=vectors_dim, distance=models.Distance.EUCLID) - local_client.recreate_collection( - COLLECTION_NAME, vectors_config=vectors_config, timeout=TIMEOUT - ) - remote_client.recreate_collection( + + local_client.create_collection(COLLECTION_NAME, vectors_config=vectors_config, timeout=TIMEOUT) + if remote_client.collection_exists(COLLECTION_NAME): + remote_client.delete_collection(COLLECTION_NAME, timeout=TIMEOUT) + remote_client.create_collection( COLLECTION_NAME, vectors_config=vectors_config, timeout=TIMEOUT ) @@ -193,12 +193,15 @@ def test_upload_collection_np_array_2d(): vectors = np.random.randn(UPLOAD_NUM_VECTORS, vectors_dim) ids = list(range(len(vectors))) vectors_config = models.VectorParams(size=vectors_dim, distance=models.Distance.EUCLID) - local_client.recreate_collection( + + local_client.create_collection( COLLECTION_NAME, vectors_config=vectors_config, timeout=TIMEOUT, ) - remote_client.recreate_collection( + if remote_client.collection_exists(COLLECTION_NAME): + remote_client.delete_collection(COLLECTION_NAME, timeout=TIMEOUT) + remote_client.create_collection( COLLECTION_NAME, vectors_config=vectors_config, timeout=TIMEOUT, @@ -221,12 +224,15 @@ def test_upload_collection_list_np_arrays(): vectors = [np.array(vector) for vector in vectors] vectors_config = models.VectorParams(size=vectors_dim, distance=models.Distance.EUCLID) ids = list(range(len(vectors))) - local_client.recreate_collection( + + local_client.create_collection( COLLECTION_NAME, vectors_config=vectors_config, timeout=TIMEOUT, ) - remote_client.recreate_collection( + if remote_client.collection_exists(COLLECTION_NAME): + remote_client.delete_collection(COLLECTION_NAME, timeout=TIMEOUT) + remote_client.create_collection( COLLECTION_NAME, vectors_config=vectors_config, timeout=TIMEOUT, @@ -267,12 +273,15 @@ def test_upload_wrong_vectors(): "text": models.VectorParams(size=vector_size, distance=models.Distance.COSINE) } sparse_vectors_config = {"text-sparse": models.SparseVectorParams()} - local_client.recreate_collection( + + local_client.create_collection( collection_name=wrong_vectors_collection, vectors_config=vectors_config, sparse_vectors_config=sparse_vectors_config, ) - remote_client.recreate_collection( + if remote_client.collection_exists(collection_name=wrong_vectors_collection): + remote_client.delete_collection(collection_name=wrong_vectors_collection) + remote_client.create_collection( collection_name=wrong_vectors_collection, vectors_config=vectors_config, sparse_vectors_config=sparse_vectors_config, diff --git a/tests/test_async_qdrant_client.py b/tests/test_async_qdrant_client.py index ab072377..413e0bc0 100644 --- a/tests/test_async_qdrant_client.py +++ b/tests/test_async_qdrant_client.py @@ -113,8 +113,6 @@ async def test_async_qdrant_client(prefer_grpc): await client.delete_collection(COLLECTION_NAME) await client.create_collection(**collection_params) - await client.recreate_collection(**collection_params) - await client.get_collection(COLLECTION_NAME) await client.get_collections() if not version_set or dev_version or minor_version >= 8: @@ -355,9 +353,9 @@ async def test_async_qdrant_client_local(): collection_name=COLLECTION_NAME, vectors_config=models.VectorParams(size=10, distance=models.Distance.EUCLID), ) + if await client.collection_exists(COLLECTION_NAME): + await client.delete_collection(COLLECTION_NAME) await client.create_collection(**collection_params) - await client.delete_collection(COLLECTION_NAME) - await client.recreate_collection(**collection_params) await client.get_collection(COLLECTION_NAME) await client.get_collections() @@ -537,7 +535,8 @@ async def test_async_qdrant_client_local(): assert (await client.retrieve(COLLECTION_NAME, ids=[1]))[0].payload == {} # region teardown - await client.delete_collection(COLLECTION_NAME) + if await client.collection_exists(COLLECTION_NAME): + await client.delete_collection(COLLECTION_NAME) collections = await client.get_collections() assert all(collection.name != COLLECTION_NAME for collection in collections.collections) diff --git a/tests/test_in_memory.py b/tests/test_in_memory.py index faaf294b..2b96f4d9 100644 --- a/tests/test_in_memory.py +++ b/tests/test_in_memory.py @@ -9,7 +9,7 @@ def qdrant() -> QdrantClient: def test_dense_in_memory_key_filter_returns_results(qdrant: QdrantClient): - qdrant.recreate_collection( + qdrant.create_collection( collection_name="test_collection", vectors_config=models.VectorParams(size=4, distance=models.Distance.DOT), ) @@ -55,7 +55,7 @@ def test_dense_in_memory_key_filter_returns_results(qdrant: QdrantClient): def test_sparse_in_memory_key_filter_returns_results(qdrant: QdrantClient): - qdrant.recreate_collection( + qdrant.create_collection( collection_name="test_collection", vectors_config={}, sparse_vectors_config={"text": models.SparseVectorParams()}, diff --git a/tests/test_local_persistence.py b/tests/test_local_persistence.py index e08f6e31..4a9bb74a 100644 --- a/tests/test_local_persistence.py +++ b/tests/test_local_persistence.py @@ -23,7 +23,9 @@ def ingest_dense_vector_data( embeddings = np.random.randn(len(lines), vector_size).tolist() client = qdrant_client.QdrantClient(path=path) - client.recreate_collection( + if client.collection_exists(collection_name): + client.delete_collection(collection_name) + client.create_collection( collection_name, vectors_config=rest.VectorParams( size=vector_size, @@ -51,7 +53,9 @@ def ingest_sparse_vector_data( sparse_vectors = generate_random_sparse_vector_list(vector_count, max_vector_size, 0.2) client = qdrant_client.QdrantClient(path=path) - client.recreate_collection( + if client.collection_exists(collection_name): + client.delete_collection(collection_name) + client.create_collection( collection_name, vectors_config={} if not add_dense_to_config diff --git a/tests/test_migrate.py b/tests/test_migrate.py index 9bf0950e..8cedc288 100644 --- a/tests/test_migrate.py +++ b/tests/test_migrate.py @@ -383,9 +383,7 @@ def test_vector_params( ), } - local_client.recreate_collection( - collection_name=collection_name, vectors_config=vectors_config - ) + local_client.create_collection(collection_name=collection_name, vectors_config=vectors_config) local_client.migrate(second_local_client) @@ -485,7 +483,7 @@ def test_recreate_collection(remote_client: QdrantClient): ) ) - remote_client.recreate_collection( + remote_client.create_collection( collection_name, vectors_config=vectors_config, shard_number=3, diff --git a/tests/test_qdrant_client.py b/tests/test_qdrant_client.py index a4607e1f..6c010d79 100644 --- a/tests/test_qdrant_client.py +++ b/tests/test_qdrant_client.py @@ -6,8 +6,10 @@ from tempfile import mkdtemp from time import sleep from typing import List + import numpy as np import pytest +from httpx import Timeout from grpc import Compression, RpcError import qdrant_client.http.exceptions @@ -199,8 +201,9 @@ def test_records_upload(prefer_grpc, parallel): ) client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), timeout=TIMEOUT, @@ -234,7 +237,8 @@ def test_records_upload(prefer_grpc, parallel): records = (Record(id=idx, vector=np.random.rand(DIM).tolist()) for idx in range(NUM_VECTORS)) - client.recreate_collection( + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), timeout=TIMEOUT, @@ -263,7 +267,9 @@ def test_point_upload(prefer_grpc, parallel): client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), timeout=TIMEOUT, @@ -295,7 +301,8 @@ def test_point_upload(prefer_grpc, parallel): assert result_count.count < 900 assert result_count.count > 100 - client.recreate_collection( + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), timeout=TIMEOUT, @@ -321,7 +328,9 @@ def test_upload_collection(prefer_grpc, parallel): batch_size = 2 client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=size, distance=Distance.DOT), timeout=TIMEOUT, @@ -346,7 +355,8 @@ def test_upload_collection(prefer_grpc, parallel): assert client.get_collection(collection_name=COLLECTION_NAME).points_count == 5 - client.recreate_collection( + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=size, distance=Distance.DOT), timeout=TIMEOUT, @@ -381,8 +391,9 @@ def test_multiple_vectors(prefer_grpc): ] client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config={ "image": VectorParams(size=DIM, distance=Distance.DOT), @@ -440,8 +451,9 @@ def test_qdrant_client_integration(prefer_grpc, numpy_upload, local_mode): client = QdrantClient(location=":memory:", prefer_grpc=prefer_grpc) else: client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), timeout=TIMEOUT, @@ -1032,8 +1044,9 @@ def test_qdrant_client_integration(prefer_grpc, numpy_upload, local_mode): @pytest.mark.parametrize("prefer_grpc", [False, True]) def test_qdrant_client_integration_update_collection(prefer_grpc): client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config={ "text": VectorParams(size=DIM, distance=Distance.DOT), @@ -1092,8 +1105,9 @@ def test_qdrant_client_integration_update_collection(prefer_grpc): @pytest.mark.parametrize("prefer_grpc", [False, True]) def test_points_crud(prefer_grpc): client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), timeout=TIMEOUT, @@ -1141,8 +1155,9 @@ def test_points_crud(prefer_grpc): @pytest.mark.parametrize("prefer_grpc", [False, True]) def test_quantization_config(prefer_grpc): client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), quantization_config=ScalarQuantization( @@ -1201,7 +1216,9 @@ def test_custom_sharding(prefer_grpc): client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) def init_collection(): - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), sharding_method=models.ShardingMethod.CUSTOM, @@ -1375,8 +1392,9 @@ def test_sparse_vectors(prefer_grpc): pytest.skip("Sparse vectors are supported since v1.7.0") client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config={}, sparse_vectors_config={ @@ -1454,8 +1472,9 @@ def test_sparse_vectors_batch(prefer_grpc): pytest.skip("Sparse vectors are supported since v1.7.0") client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config={}, sparse_vectors_config={ @@ -1536,8 +1555,9 @@ def test_sparse_vectors_batch(prefer_grpc): @pytest.mark.parametrize("prefer_grpc", [False, True]) def test_vector_update(prefer_grpc): client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), timeout=TIMEOUT, @@ -1595,8 +1615,9 @@ def test_vector_update(prefer_grpc): @pytest.mark.parametrize("prefer_grpc", [False, True]) def test_conditional_payload_update(prefer_grpc): client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), timeout=TIMEOUT, @@ -1634,8 +1655,9 @@ def test_conditional_payload_update(prefer_grpc): @pytest.mark.parametrize("prefer_grpc", [False, True]) def test_conditional_payload_update_2(prefer_grpc): client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), timeout=TIMEOUT, @@ -1714,8 +1736,9 @@ def test_insert_float(): def test_locks(): client = QdrantClient(timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=VectorParams(size=DIM, distance=Distance.DOT), timeout=TIMEOUT, @@ -1760,8 +1783,9 @@ def test_locks(): @pytest.mark.parametrize("prefer_grpc", [False, True]) def test_empty_vector(prefer_grpc): client = QdrantClient(prefer_grpc=prefer_grpc, timeout=TIMEOUT) - - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=TIMEOUT) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config={}, timeout=TIMEOUT, @@ -1820,19 +1844,25 @@ def test_client_close(): # region http client_http = QdrantClient(timeout=TIMEOUT) - client_http.recreate_collection( + if client_http.collection_exists("test"): + client_http.delete_collection("test") + client_http.create_collection( "test", vectors_config=VectorParams(size=100, distance=Distance.COSINE) ) client_http.close() with pytest.raises(qdrant_exceptions.ResponseHandlingException): - client_http.recreate_collection( + if client_http.collection_exists("test"): + client_http.delete_collection("test") + client_http.create_collection( "test", vectors_config=VectorParams(size=100, distance=Distance.COSINE) ) # endregion # region grpc client_grpc = QdrantClient(prefer_grpc=True, timeout=TIMEOUT) - client_grpc.recreate_collection( + if client_grpc.collection_exists("test"): + client_grpc.delete_collection("test") + client_grpc.create_collection( "test", vectors_config=VectorParams(size=100, distance=Distance.COSINE) ) client_grpc.close() @@ -1873,7 +1903,9 @@ def test_client_close(): # region local local_client_in_mem = QdrantClient(":memory:") - local_client_in_mem.recreate_collection( + if local_client_in_mem.collection_exists("test"): + local_client_in_mem.delete_collection("test") + local_client_in_mem.create_collection( "test", vectors_config=VectorParams(size=100, distance=Distance.COSINE) ) local_client_in_mem.close() @@ -1885,24 +1917,30 @@ def test_client_close(): ) with pytest.raises(RuntimeError): - local_client_in_mem.create_collection( - "test", vectors_config=VectorParams(size=100, distance=Distance.COSINE) - ) + if not local_client_in_mem.collection_exists("test"): + local_client_in_mem.create_collection( + "test", vectors_config=VectorParams(size=100, distance=Distance.COSINE) + ) with pytest.raises(RuntimeError): - local_client_in_mem.delete_collection("test") + if local_client_in_mem.collection_exists("test"): + local_client_in_mem.delete_collection("test") with tempfile.TemporaryDirectory() as tmpdir: path = tmpdir + "/test.db" local_client_persist_1 = QdrantClient(path=path) - local_client_persist_1.recreate_collection( + if local_client_persist_1.collection_exists("test"): + local_client_persist_1.delete_collection("test") + local_client_persist_1.create_collection( "test", vectors_config=VectorParams(size=100, distance=Distance.COSINE) ) local_client_persist_1.close() local_client_persist_2 = QdrantClient(path=path) - local_client_persist_2.recreate_collection( + if local_client_persist_2.collection_exists("test"): + local_client_persist_2.delete_collection("test") + local_client_persist_2.create_collection( "test", vectors_config=VectorParams(size=100, distance=Distance.COSINE) ) local_client_persist_2.close() @@ -1910,10 +1948,6 @@ def test_client_close(): def test_timeout_propagation(): - import time - - from httpx import Timeout - client = QdrantClient() vectors_config = models.VectorParams(size=2, distance=models.Distance.COSINE) with pytest.raises( @@ -1922,9 +1956,13 @@ def test_timeout_propagation(): # timeout is Optional[int] # if we set it to 0 - recreate_collection raises operation is in progress instead of timed out client.http.client._client._timeout = Timeout(0.01) - client.recreate_collection(collection_name=COLLECTION_NAME, vectors_config=vectors_config) - time.sleep(0.5) - client.recreate_collection( + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME) + client.create_collection(collection_name=COLLECTION_NAME, vectors_config=vectors_config) + sleep(0.5) + if client.collection_exists(COLLECTION_NAME): + client.delete_collection(collection_name=COLLECTION_NAME, timeout=10) + client.create_collection( collection_name=COLLECTION_NAME, vectors_config=vectors_config, timeout=10 ) @@ -1937,10 +1975,11 @@ def test_grpc_options(): assert client._client._grpc_options == {"grpc.max_send_message_length": 3} with pytest.raises(RpcError): - client.create_collection( - "grpc_collection", - vectors_config=models.VectorParams(size=100, distance=models.Distance.COSINE), - ) + if not client.collection_exists("grpc_collection"): + client.create_collection( + "grpc_collection", + vectors_config=models.VectorParams(size=100, distance=models.Distance.COSINE), + ) def test_grpc_compression():