qdrant: enforce int/UUID point ids; preserve original id in payload; add error handling
This commit is contained in:
@@ -148,7 +148,27 @@ def _build_filter(metadata: Dict[str, Any]) -> Optional[Filter]:
|
|||||||
|
|
||||||
|
|
||||||
def _point_id(raw: Optional[str]) -> str:
|
def _point_id(raw: Optional[str]) -> str:
|
||||||
return raw or uuid.uuid4().hex
|
"""Return a Qdrant-compatible point id.
|
||||||
|
|
||||||
|
Qdrant accepts either an unsigned integer or a UUID string (with hyphens).
|
||||||
|
If the provided `raw` value is an int or valid UUID we return it (as int or str).
|
||||||
|
Otherwise we generate a new UUID string and the caller should store the
|
||||||
|
original `raw` value in the point payload under `_original_id`.
|
||||||
|
"""
|
||||||
|
if not raw:
|
||||||
|
return str(uuid.uuid4())
|
||||||
|
# allow integer ids
|
||||||
|
try:
|
||||||
|
return int(raw)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
# allow UUID strings
|
||||||
|
try:
|
||||||
|
u = uuid.UUID(raw)
|
||||||
|
return str(u)
|
||||||
|
except Exception:
|
||||||
|
# fallback: generate a UUID
|
||||||
|
return str(uuid.uuid4())
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -223,12 +243,19 @@ async def upsert_url(req: UpsertUrlRequest):
|
|||||||
vector = await _embed_url(req.url)
|
vector = await _embed_url(req.url)
|
||||||
pid = _point_id(req.id)
|
pid = _point_id(req.id)
|
||||||
payload = {**req.metadata, "source_url": req.url}
|
payload = {**req.metadata, "source_url": req.url}
|
||||||
|
# preserve original user-provided id if it wasn't usable as a point id
|
||||||
|
if req.id is not None and str(pid) != str(req.id):
|
||||||
|
payload["_original_id"] = req.id
|
||||||
col = _col(req.collection)
|
col = _col(req.collection)
|
||||||
|
|
||||||
|
try:
|
||||||
client.upsert(
|
client.upsert(
|
||||||
collection_name=col,
|
collection_name=col,
|
||||||
points=[PointStruct(id=pid, vector=vector, payload=payload)],
|
points=[PointStruct(id=pid, vector=vector, payload=payload)],
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
return {"id": pid, "collection": col, "dim": len(vector)}
|
return {"id": pid, "collection": col, "dim": len(vector)}
|
||||||
|
|
||||||
|
|
||||||
@@ -252,12 +279,19 @@ async def upsert_file(
|
|||||||
payload = json.loads(metadata_json)
|
payload = json.loads(metadata_json)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
raise HTTPException(400, "metadata_json must be valid JSON")
|
raise HTTPException(400, "metadata_json must be valid JSON")
|
||||||
|
# preserve original user-provided id if it wasn't usable as a point id
|
||||||
|
if id is not None and str(pid) != str(id):
|
||||||
|
payload["_original_id"] = id
|
||||||
|
|
||||||
col = _col(collection)
|
col = _col(collection)
|
||||||
|
try:
|
||||||
client.upsert(
|
client.upsert(
|
||||||
collection_name=col,
|
collection_name=col,
|
||||||
points=[PointStruct(id=pid, vector=vector, payload=payload)],
|
points=[PointStruct(id=pid, vector=vector, payload=payload)],
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
|
|
||||||
return {"id": pid, "collection": col, "dim": len(vector)}
|
return {"id": pid, "collection": col, "dim": len(vector)}
|
||||||
|
|
||||||
|
|
||||||
@@ -266,10 +300,16 @@ def upsert_vector(req: UpsertVectorRequest):
|
|||||||
"""Store a pre-computed vector directly (skip CLIP embedding)."""
|
"""Store a pre-computed vector directly (skip CLIP embedding)."""
|
||||||
pid = _point_id(req.id)
|
pid = _point_id(req.id)
|
||||||
col = _col(req.collection)
|
col = _col(req.collection)
|
||||||
|
payload = dict(req.metadata or {})
|
||||||
|
if req.id is not None and str(pid) != str(req.id):
|
||||||
|
payload["_original_id"] = req.id
|
||||||
|
try:
|
||||||
client.upsert(
|
client.upsert(
|
||||||
collection_name=col,
|
collection_name=col,
|
||||||
points=[PointStruct(id=pid, vector=req.vector, payload=req.metadata)],
|
points=[PointStruct(id=pid, vector=req.vector, payload=payload)],
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(500, str(e))
|
||||||
return {"id": pid, "collection": col, "dim": len(req.vector)}
|
return {"id": pid, "collection": col, "dim": len(req.vector)}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user