mirror of
https://github.com/hwchase17/langchain.git
synced 2025-07-14 08:56:27 +00:00
qdrant[patch]: Use collection_exists API instead of exceptions (#22764)
## Description Currently, the Qdrant integration relies on exceptions raised by [`get_collection` ](https://qdrant.tech/documentation/concepts/collections/#collection-info) to check if a collection exists. Using [`collection_exists`](https://qdrant.tech/documentation/concepts/collections/#check-collection-existence) is recommended to avoid missing any unhandled exceptions. This PR addresses this. ## Testing All integration and unit tests pass. No user-facing changes.
This commit is contained in:
parent
c417803908
commit
e002c855bd
@ -23,14 +23,12 @@ from typing import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from grpc import RpcError # type: ignore
|
|
||||||
from langchain_core.documents import Document
|
from langchain_core.documents import Document
|
||||||
from langchain_core.embeddings import Embeddings
|
from langchain_core.embeddings import Embeddings
|
||||||
from langchain_core.runnables.config import run_in_executor
|
from langchain_core.runnables.config import run_in_executor
|
||||||
from langchain_core.vectorstores import VectorStore
|
from langchain_core.vectorstores import VectorStore
|
||||||
from qdrant_client import AsyncQdrantClient, QdrantClient
|
from qdrant_client import AsyncQdrantClient, QdrantClient
|
||||||
from qdrant_client.http import models
|
from qdrant_client.http import models
|
||||||
from qdrant_client.http.exceptions import UnexpectedResponse
|
|
||||||
from qdrant_client.local.async_qdrant_local import AsyncQdrantLocal
|
from qdrant_client.local.async_qdrant_local import AsyncQdrantLocal
|
||||||
|
|
||||||
from langchain_qdrant._utils import maximal_marginal_relevance
|
from langchain_qdrant._utils import maximal_marginal_relevance
|
||||||
@ -1636,14 +1634,16 @@ class Qdrant(VectorStore):
|
|||||||
path=path,
|
path=path,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
try:
|
collection_exists = client.collection_exists(collection_name)
|
||||||
# Skip any validation in case of forced collection recreate.
|
|
||||||
if force_recreate:
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
|
if collection_exists and force_recreate:
|
||||||
|
client.delete_collection(collection_name)
|
||||||
|
collection_exists = False
|
||||||
|
|
||||||
|
if collection_exists:
|
||||||
# Get the vector configuration of the existing collection and vector, if it
|
# Get the vector configuration of the existing collection and vector, if it
|
||||||
# was specified. If the old configuration does not match the current one,
|
# was specified. If the old configuration does not match the current one,
|
||||||
# an exception is being thrown.
|
# an exception is raised.
|
||||||
collection_info = client.get_collection(collection_name=collection_name)
|
collection_info = client.get_collection(collection_name=collection_name)
|
||||||
current_vector_config = collection_info.config.params.vectors
|
current_vector_config = collection_info.config.params.vectors
|
||||||
if isinstance(current_vector_config, dict) and vector_name is not None:
|
if isinstance(current_vector_config, dict) and vector_name is not None:
|
||||||
@ -1700,7 +1700,7 @@ class Qdrant(VectorStore):
|
|||||||
f"If you want to recreate the collection, set `force_recreate` "
|
f"If you want to recreate the collection, set `force_recreate` "
|
||||||
f"parameter to `True`."
|
f"parameter to `True`."
|
||||||
)
|
)
|
||||||
except (UnexpectedResponse, RpcError, ValueError):
|
else:
|
||||||
vectors_config = models.VectorParams(
|
vectors_config = models.VectorParams(
|
||||||
size=vector_size,
|
size=vector_size,
|
||||||
distance=models.Distance[distance_func],
|
distance=models.Distance[distance_func],
|
||||||
@ -1714,8 +1714,6 @@ class Qdrant(VectorStore):
|
|||||||
vector_name: vectors_config,
|
vector_name: vectors_config,
|
||||||
}
|
}
|
||||||
|
|
||||||
if client.collection_exists(collection_name):
|
|
||||||
client.delete_collection(collection_name)
|
|
||||||
client.create_collection(
|
client.create_collection(
|
||||||
collection_name=collection_name,
|
collection_name=collection_name,
|
||||||
vectors_config=vectors_config,
|
vectors_config=vectors_config,
|
||||||
@ -1795,14 +1793,17 @@ class Qdrant(VectorStore):
|
|||||||
path=path,
|
path=path,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
try:
|
|
||||||
# Skip any validation in case of forced collection recreate.
|
|
||||||
if force_recreate:
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
|
collection_exists = client.collection_exists(collection_name)
|
||||||
|
|
||||||
|
if collection_exists and force_recreate:
|
||||||
|
client.delete_collection(collection_name)
|
||||||
|
collection_exists = False
|
||||||
|
|
||||||
|
if collection_exists:
|
||||||
# Get the vector configuration of the existing collection and vector, if it
|
# Get the vector configuration of the existing collection and vector, if it
|
||||||
# was specified. If the old configuration does not match the current one,
|
# was specified. If the old configuration does not match the current one,
|
||||||
# an exception is being thrown.
|
# an exception is raised.
|
||||||
collection_info = client.get_collection(collection_name=collection_name)
|
collection_info = client.get_collection(collection_name=collection_name)
|
||||||
current_vector_config = collection_info.config.params.vectors
|
current_vector_config = collection_info.config.params.vectors
|
||||||
if isinstance(current_vector_config, dict) and vector_name is not None:
|
if isinstance(current_vector_config, dict) and vector_name is not None:
|
||||||
@ -1861,7 +1862,7 @@ class Qdrant(VectorStore):
|
|||||||
f"recreate the collection, set `force_recreate` parameter to "
|
f"recreate the collection, set `force_recreate` parameter to "
|
||||||
f"`True`."
|
f"`True`."
|
||||||
)
|
)
|
||||||
except (UnexpectedResponse, RpcError, ValueError):
|
else:
|
||||||
vectors_config = models.VectorParams(
|
vectors_config = models.VectorParams(
|
||||||
size=vector_size,
|
size=vector_size,
|
||||||
distance=models.Distance[distance_func],
|
distance=models.Distance[distance_func],
|
||||||
@ -1875,7 +1876,7 @@ class Qdrant(VectorStore):
|
|||||||
vector_name: vectors_config,
|
vector_name: vectors_config,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.recreate_collection(
|
client.create_collection(
|
||||||
collection_name=collection_name,
|
collection_name=collection_name,
|
||||||
vectors_config=vectors_config,
|
vectors_config=vectors_config,
|
||||||
shard_number=shard_number,
|
shard_number=shard_number,
|
||||||
|
15
libs/partners/qdrant/poetry.lock
generated
15
libs/partners/qdrant/poetry.lock
generated
@ -1,4 +1,4 @@
|
|||||||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "annotated-types"
|
name = "annotated-types"
|
||||||
@ -463,7 +463,7 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langchain-core"
|
name = "langchain-core"
|
||||||
version = "0.2.0rc1"
|
version = "0.2.5"
|
||||||
description = "Building applications with LLMs through composability"
|
description = "Building applications with LLMs through composability"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8.1,<4.0"
|
python-versions = ">=3.8.1,<4.0"
|
||||||
@ -472,28 +472,25 @@ develop = true
|
|||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
jsonpatch = "^1.33"
|
jsonpatch = "^1.33"
|
||||||
langsmith = "^0.1.0"
|
langsmith = "^0.1.75"
|
||||||
packaging = "^23.2"
|
packaging = "^23.2"
|
||||||
pydantic = ">=1,<3"
|
pydantic = ">=1,<3"
|
||||||
PyYAML = ">=5.3"
|
PyYAML = ">=5.3"
|
||||||
tenacity = "^8.1.0"
|
tenacity = "^8.1.0"
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
extended-testing = ["jinja2 (>=3,<4)"]
|
|
||||||
|
|
||||||
[package.source]
|
[package.source]
|
||||||
type = "directory"
|
type = "directory"
|
||||||
url = "../../core"
|
url = "../../core"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langsmith"
|
name = "langsmith"
|
||||||
version = "0.1.58"
|
version = "0.1.76"
|
||||||
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
|
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "<4.0,>=3.8.1"
|
python-versions = "<4.0,>=3.8.1"
|
||||||
files = [
|
files = [
|
||||||
{file = "langsmith-0.1.58-py3-none-any.whl", hash = "sha256:1148cc836ec99d1b2f37cd2fa3014fcac213bb6bad798a2b21bb9111c18c9768"},
|
{file = "langsmith-0.1.76-py3-none-any.whl", hash = "sha256:4b8cb14f2233d9673ce9e6e3d545359946d9690a2c1457ab01e7459ec97b964e"},
|
||||||
{file = "langsmith-0.1.58.tar.gz", hash = "sha256:a5060933c1fb3006b498ec849677993329d7e6138bdc2ec044068ab806e09c39"},
|
{file = "langsmith-0.1.76.tar.gz", hash = "sha256:5829f997495c0f9a39f91fe0a57e0cb702e8642e6948945f5bb9f46337db7732"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "langchain-qdrant"
|
name = "langchain-qdrant"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
description = "An integration package connecting Qdrant and LangChain"
|
description = "An integration package connecting Qdrant and LangChain"
|
||||||
authors = []
|
authors = []
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
Loading…
Reference in New Issue
Block a user