Weaviate Python Client (Latest) and DateType issue

Hi there :slight_smile:

I am facing an issue with Date Datatype which is driving me crazy. i am using Langchain but I do not use Langchain to manage the vector db directly.

import weaviate
from weaviate.classes.config import Configure, Property, DataType, VectorDistances
from weaviate.classes.query import MetadataQuery

def _create_collection(self) -> None:
        """Create a new collection for storing memories if it doesn't exist."""
        if self._collection_exists():
            self.logger.info(f"Collection {self.COLLECTION_NAME} already exists")
            return
            
        try:
            # Create the collection with the exact configuration from the notebook
            self.logger.info(f"Creating collection {self.COLLECTION_NAME}")
            self.client.collections.create(
                self.COLLECTION_NAME,
                vectorizer_config=[
                    Configure.NamedVectors.text2vec_transformers(
                        name="text_vector",
                        source_properties=["text"],
                        vector_index_config=Configure.VectorIndex.hnsw(
                            distance_metric=VectorDistances.COSINE
                        )
                    )
                ],
                properties=[
                    Property(name="text", data_type=DataType.TEXT),
                    Property(name="timestamp", data_type=DataType.DATE),
                    Property(name="uuid", data_type=DataType.UUID)
                ]
            )
            
            # Verify the collection was created
            if self._collection_exists():
                self.logger.info(f"Successfully created collection {self.COLLECTION_NAME}")
            else:
                self.logger.error(f"Failed to verify collection was created")
                
        except Exception as e:
            self.logger.error(f"Error creating collection: {str(e)}")
            self.logger.error(traceback.format_exc())
            raise

I have tried millions of different combination but i am always getting the same error over and over again:

weaviate.exceptions.UnexpectedStatusCodeError: Object was not added! Unexpected status code: 422, with response body: {'error': [{'message': "invalid object: invalid date property 'timestamp' on class 'Long_term_memory': requires a string with a RFC3339 formatted date, but the given value is '2025-04-02T11:04:10.160695'"}]}.

the function responsible for the object creation:

def store_memory(self, text: str, metadata: dict) -> None:
        """Store a new memory in the vector store."""
        try:
            # Create collection if it doesn't exist
            if not self._collection_exists():
                self._create_collection()
                
            self.logger.info(f"Storing memory: {text[:50]}...")
            collection = self.client.collections.get(self.COLLECTION_NAME)
            
            # Check if similar memory exists
            similar_memory = self.find_similar_memory(text)
            if similar_memory and similar_memory.id:
                self.logger.info(f"Updating existing memory with ID: {similar_memory.id}")
                # For updates we'll use the existing UUID
                uuid_value = similar_memory.id
            else:
                # For new entries, get UUID from metadata if available
                uuid_value = metadata.get("uuid") or metadata.get("id")
            
            # Create a datetime object with UTC timezone
            now = datetime.now(timezone.utc)
            
            # Format as RFC3339 string with 'Z' suffix
            # Example: 2025-04-02T10:20:31.183Z
            timestamp_rfc3339 = now.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
            
            # Create properties dictionary WITHOUT id/uuid
            properties = {
                "text": text,
                "timestamp": timestamp_rfc3339,  # Use the formatted string
            }
            
            # Add any other metadata EXCEPT id/uuid
            for key, value in metadata.items():
                if key not in ["id", "uuid"]:
                    properties[key] = value

            self.logger.info(f"Storing with properties: {properties}")
            
            # Use direct insert instead of batch
            if uuid_value:
                # If we have a UUID, use it explicitly
                collection.data.insert(
                    properties=properties,
                    uuid=uuid_value
                )
            else:
                # Let Weaviate generate a UUID
                collection.data.insert(
                    properties=properties
                )
            
            self.logger.info("Memory stored successfully")
        except Exception as e:
            self.logger.error(f"Error in store_memory: {str(e)}")
            self.logger.error(traceback.format_exc())
            raise

I am going to drop the date because i am sick and tired :smiley: but perhaps someone will catch the issue

many thanks in advance.
BR,
Wasami

sorry i have fixed it. I share some functions between Qdrant and Weaviate and the date was getting altered in a not compliant way (but compliant with Qdrant). for reference if someone will never face the same issue:

def store_memory(self, text: str, metadata: dict) -> None:
        """Store a new memory in the vector store."""
        try:
            # Create collection if it doesn't exist
            if not self._collection_exists():
                self._create_collection()
                
            self.logger.info(f"Storing memory: {text[:50]}...")
            collection = self.client.collections.get(self.COLLECTION_NAME)
            
            # Check if similar memory exists
            similar_memory = self.find_similar_memory(text)
            if similar_memory and similar_memory.id:
                self.logger.info(f"Updating existing memory with ID: {similar_memory.id}")
                # For updates we'll use the existing UUID
                uuid_value = similar_memory.id
            else:
                # For new entries, get UUID from metadata if available
                uuid_value = metadata.get("uuid") or metadata.get("id")
            
            # Create properties dictionary WITHOUT id/uuid
            properties = {
                "text": text,
            }
            
            # Format timestamp for Weaviate (RFC3339 with timezone)
            if "timestamp" in metadata:
                # If timestamp is a string, try to parse it
                if isinstance(metadata["timestamp"], str):
                    try:
                        # Try to parse the timestamp string
                        dt = datetime.fromisoformat(metadata["timestamp"].replace('Z', '+00:00'))
                        # Convert to local timezone and format as RFC3339
                        local_time = dt.astimezone()
                        properties["timestamp"] = local_time.isoformat()
                    except ValueError:
                        # If parsing fails, use current time
                        local_time = datetime.now(timezone.utc).astimezone()
                        properties["timestamp"] = local_time.isoformat()
                else:
                    # If timestamp is already a datetime object, use it directly
                    dt = metadata["timestamp"]
                    if dt.tzinfo is None:
                        # If no timezone info, assume UTC
                        dt = dt.replace(tzinfo=timezone.utc)
                    local_time = dt.astimezone()
                    properties["timestamp"] = local_time.isoformat()
            else:
                # If no timestamp provided, use current time
                local_time = datetime.now(timezone.utc).astimezone()
                properties["timestamp"] = local_time.isoformat()
            
            # Add any other metadata EXCEPT id/uuid
            for key, value in metadata.items():
                if key not in ["id", "uuid", "timestamp"]:  # Skip id, uuid, and timestamp as we've handled them
                    properties[key] = value

            self.logger.info(f"Storing with properties: {properties}")
            
            # Use batch approach instead of direct insert
            with collection.batch.dynamic() as batch:
                if uuid_value:
                    # If we have a UUID, use it explicitly
                    batch.add_object(
                        properties=properties,
                        uuid=uuid_value
                    )
                else:
                    # Let Weaviate generate a UUID
                    batch.add_object(
                        properties=properties
                    )
                
                # Check for errors
                if batch.number_errors > 0:
                    failed_objects = collection.batch.failed_objects
                    if failed_objects:
                        self.logger.error(f"Failed to store memory: {failed_objects[0]}")
                        raise Exception(f"Failed to store memory: {failed_objects[0]}")
            
            self.logger.info("Memory stored successfully")
        except Exception as e:
            self.logger.error(f"Error in store_memory: {str(e)}")
            self.logger.error(traceback.format_exc())
            raise

many thanks

Hi @Wasami_Kirua !!

Welcome to our community :hugs:

And thanks for sharing your solution! We really appreciate it.