fix(weaviate): don't write OutputData model fields as properties on update (#6149)

Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
This commit is contained in:
Aditya Jethani
2026-07-10 20:47:59 +05:30
committed by GitHub
co-authored by Kartik
parent 28e4d819f8
commit f69f8dcc7b
2 changed files with 46 additions and 8 deletions
+2 -8
View File
@@ -1,6 +1,6 @@
import logging import logging
import uuid import uuid
from typing import Dict, List, Mapping, Optional from typing import Dict, List, Optional
from urllib.parse import urlparse from urllib.parse import urlparse
from pydantic import BaseModel from pydantic import BaseModel
@@ -297,13 +297,7 @@ class Weaviate(VectorStoreBase):
collection.data.update(uuid=vector_id, properties=payload) collection.data.update(uuid=vector_id, properties=payload)
if vector: if vector:
existing_data = self.get(vector_id) collection.data.update(uuid=vector_id, vector=vector)
if existing_data:
existing_data = dict(existing_data)
if "id" in existing_data:
del existing_data["id"]
existing_payload: Mapping[str, str] = existing_data
collection.data.update(uuid=vector_id, properties=existing_payload, vector=vector)
def get(self, vector_id) -> Optional[OutputData]: def get(self, vector_id) -> Optional[OutputData]:
""" """
+44
View File
@@ -220,6 +220,50 @@ class TestWeaviateDB(unittest.TestCase):
self.client_mock.collections.delete.assert_called_once_with("test_collection") self.client_mock.collections.delete.assert_called_once_with("test_collection")
self.client_mock.collections.create.assert_called_once() self.client_mock.collections.create.assert_called_once()
def test_update_preserves_properties_and_does_not_write_model_fields(self):
# Regression: the vector branch of update() previously resent
# dict(OutputData) as properties, i.e. the model field names
# {"id", "score", "payload"}, corrupting the stored object instead of
# preserving its real properties.
valid_uuid = str(uuid.uuid4())
collection = self.client_mock.collections.get.return_value
# Mock get() so that, on the buggy code path, the vector branch can run
# to completion and actually write its (wrong) properties.
mock_response = MagicMock()
mock_response.properties = {"data": "existing", "hash": "abc123"}
mock_response.uuid = valid_uuid
collection.query.fetch_object_by_id.return_value = mock_response
new_payload = {
"data": "updated memory",
"hash": "def456",
"user_id": "user_123",
}
self.weaviate_db.update(
vector_id=valid_uuid,
vector=[0.1] * 1536,
payload=new_payload,
)
update_calls = collection.data.update.call_args_list
# The payload branch updates the real properties.
property_updates = [c for c in update_calls if "properties" in c.kwargs]
self.assertEqual(len(property_updates), 1)
self.assertEqual(property_updates[0].kwargs["properties"], new_payload)
# No update call may write the OutputData model field names as properties.
for call in update_calls:
props = call.kwargs.get("properties", {})
self.assertNotIn("score", props)
self.assertNotIn("payload", props)
# The vector branch updates the vector without touching properties.
vector_updates = [c for c in update_calls if "vector" in c.kwargs]
self.assertEqual(len(vector_updates), 1)
self.assertNotIn("properties", vector_updates[0].kwargs)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()