AttributeError: 'DataObject' object has no attribute 'items' in v4 Python Client

Hi!

I’m using Weaviate (Version 1.22.3) and Python client V4 (Version 4.3b2). When trying to load data with the following code. I get the error AttributeError: 'DataObject' object has no attribute 'items'

Code:

import weaviate
import weaviate.classes as wvc
...
 wvc.DataObject(
            properties={
                "title": capture.title,
                "text": capture.text,
            },
            vector=list(embedding_model.embed(capture.text))[0],
        )
_extension.data.insert(data_object)

Error:

Traceback (most recent call last):
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py", line 408, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 84, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/fastapi/applications.py", line 1106, in __call__
    await super().__call__(scope, receive, send)
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/starlette/applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
    raise exc
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__
    raise e
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/starlette/routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/starlette/routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
               ^^^^^^^^^^^^^^^^^^^
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/fastapi/routing.py", line 274, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
    return await dependant.call(**values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/maruthi/oasis/_extension/backend/app/api/handlers/_extension.py", line 123, in capture
    web_extension.data.insert(data_object)
  File "/Users/maruthi/.pyenv/versions/_extension/lib/python3.11/site-packages/weaviate/collections/data.py", line 348, in insert
    "properties": self._serialize_properties(properties),
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/maruthi/.pyenv/versions/chrome_extension/lib/python3.11/site-packages/weaviate/collections/data.py", line 265, in _serialize_properties
    for key, val in data.items()
                    ^^^^^^^^^^
AttributeError: 'DataObject' object has no attribute 'items'

Hi @Maruthi !!

Thanks jumping in on our new V4 client!! :hugs:

~I believe we have a bug :beetle: here!~ (or not)

consider the following code, based on your previous thread:

import json
import requests
import weaviate
import weaviate.classes as wvc
from fastembed.embedding import FlagEmbedding as Embedding

client = weaviate.connect_to_local(
    port=8080,
    grpc_port=50051
)

embedding_model = Embedding(model_name="BAAI/bge-base-en", max_length=512)

if client.collections.exists("new"):
    client.collections.delete("new") 

questions = client.collections.create(
    name="new",
    vectorizer_config=None,
    generative_config=None,
)

resp = requests.get(
    "https://raw.githubusercontent.com/weaviate-tutorials/quickstart/main/data/jeopardy_tiny.json"
)
data = json.loads(resp.text)
question_objs = list()
for i, d in enumerate(data):
    vec = list(embedding_model.embed(d["Question"]))[0]
    print(f"importing question: {i+1}")
    question_objs.append(
        wvc.DataObject(
            properties={
                "answer": d["Answer"],
                "question": d["Question"],
                "category": d["Category"],
                "test": "test",
            },
            vector=vec
        )
    )

questions = client.collections.get("new")

# this doesn't work
#questions.data.insert(question_objs[0]) 
# this works
questions.data.insert_many([question_objs[0]]) 

I will poke about this internally. I was able to use insert() but only when I don’t provide the vectors.

Thanks for reporting this!

1 Like

Hi @Maruthi !

With the help of our good friend @jphwang “I can see it clear now, the rain is gone” :rofl:

while insert_many expects a list of wvc.DataObject, insert expects the object properties as it’s arguments.

Check here for the proper way to call insert:

jeopardy = client.collections.get("JeopardyQuestion")
uuid = jeopardy.data.insert(
    properties={
        "question": "This vector DB is OSS and supports automatic property type inference on import",
        "answer": "Weaviate",
    },
    uuid="12345678-e64f-5d94-90db-c8cfa3fc1234",
    vector=[0.12345] * 1536
)

print(uuid)  # the return value is the object's UUID
1 Like

Thank you @DudaNogueira. Still trying to get my bearings around Weaviate.

If I use insert_one as you have suggested, I will need to provide the uuid and this will be a hassle. So insert_many with questions.data.insert_many([question_objs[0]]) looks like a better option. Will there be any performance issues if I go with the insert_many instead of insert_one or are there any other performance considerations I need to keep in mind for these methods?

Hi!

The uuid argument in insert is optional.

It seems insert_many will use GRPC while insert will use the rest API.

I believe that GRPC will be more performant.

1 Like

Thank you, @DudaNogueira. This helps!