Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions integration/test_collection_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import weaviate
import weaviate.classes as wvc
from integration.conftest import (
ClientFactory,
CollectionFactory,
OpenAICollection,
_sanitize_collection_name,
Expand Down Expand Up @@ -1950,3 +1951,91 @@ def test_object_ttl_update(collection_factory: CollectionFactory) -> None:
)
conf = collection.config.get()
assert conf.object_ttl_config is None


def test_object_ttl_roundtrip_from_dict(
collection_factory: CollectionFactory, client_factory: ClientFactory
) -> None:
dummy = collection_factory("dummy")
if dummy._connection._weaviate_version.is_lower_than(1, 35, 0):
pytest.skip("object ttl is not supported in Weaviate versions lower than 1.35.0")

client = client_factory()

# (schema_to_create, expected_object_ttl_config_dict)
test_cases = [
Comment thread
dudanogueira marked this conversation as resolved.
Outdated
# deleteOn: _creationTimeUnix
(
{
"class": "CollectionTTLRoundtripCreation",
"objectTtlConfig": {
"enabled": True,
"defaultTtl": 60,
"deleteOn": "_creationTimeUnix",
"filterExpiredObjects": True,
},
},
{
"enabled": True,
"defaultTtl": 60,
"deleteOn": "_creationTimeUnix",
"filterExpiredObjects": True,
},
),
# deleteOn: _lastUpdateTimeUnix
(
{
"class": "CollectionTTLRoundtripUpdate",
"objectTtlConfig": {
"enabled": True,
"defaultTtl": 3600,
"deleteOn": "_lastUpdateTimeUnix",
"filterExpiredObjects": True,
},
},
{
"enabled": True,
"defaultTtl": 3600,
"deleteOn": "_lastUpdateTimeUnix",
"filterExpiredObjects": True,
},
),
# deleteOn: custom date property
(
{
"class": "CollectionTTLRoundtripDateProp",
"properties": [
{
"name": "reference_date",
"dataType": ["date"],
}
],
"objectTtlConfig": {
"enabled": True,
"defaultTtl": 123,
"deleteOn": "reference_date",
"filterExpiredObjects": True,
},
},
{
"enabled": True,
"defaultTtl": 123,
"deleteOn": "reference_date",
"filterExpiredObjects": True,
},
),
]

for schema, expected_ttl_dict in test_cases:
Comment thread
dudanogueira marked this conversation as resolved.
Outdated
name = schema["class"]
client.collections.delete(name)
try:
client.collections.create_from_dict(schema)
config = client.collections.export_config(name)
assert config.object_ttl_config is not None, f"object_ttl_config is None for {name}"
assert config.object_ttl_config.to_dict() == expected_ttl_dict, (
f"Round-trip mismatch for {name}: "
f"got {config.object_ttl_config.to_dict()}, expected {expected_ttl_dict}"
)
Comment thread
dudanogueira marked this conversation as resolved.
Outdated
finally:
client.collections.delete(name)
54 changes: 47 additions & 7 deletions test/collection/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
_RerankerProvider,
_VectorizerConfigCreate,
)
from weaviate.collections.classes.config_methods import _get_object_ttl_config
from weaviate.collections.classes.config_named_vectors import _NamedVectorConfigCreate
from weaviate.collections.classes.config_vectorizers import (
Multi2VecField,
Expand Down Expand Up @@ -2621,9 +2622,9 @@ def test_config_with_vectors(vector_config: List[_VectorConfigCreate], expected:
),
{
"enabled": True,
"timeToLive": 86400,
"defaultTtl": 86400,
"filterExpiredObjects": True,
"deleteOn": "creationTime",
"deleteOn": "_creationTimeUnix",
},
),
# delete_by_update_time
Expand All @@ -2636,9 +2637,9 @@ def test_config_with_vectors(vector_config: List[_VectorConfigCreate], expected:
),
{
"enabled": True,
"timeToLive": 604800,
"defaultTtl": 604800,
"filterExpiredObjects": False,
"deleteOn": "updateTime",
"deleteOn": "_lastUpdateTimeUnix",
},
),
# delete_by_date_property
Expand All @@ -2651,7 +2652,7 @@ def test_config_with_vectors(vector_config: List[_VectorConfigCreate], expected:
),
{
"enabled": True,
"timeToLive": 5400,
"defaultTtl": 5400,
"filterExpiredObjects": True,
"deleteOn": "releaseDate",
},
Expand All @@ -2667,7 +2668,7 @@ def test_config_with_vectors(vector_config: List[_VectorConfigCreate], expected:
{
"enabled": True,
"filterExpiredObjects": False,
"deleteOn": "creationTime",
"deleteOn": "_creationTimeUnix",
},
),
# negative offset (delete_by_date_property with offset before date)
Expand All @@ -2680,7 +2681,7 @@ def test_config_with_vectors(vector_config: List[_VectorConfigCreate], expected:
),
{
"enabled": True,
"timeToLive": -3600,
"defaultTtl": -3600,
"filterExpiredObjects": True,
"deleteOn": "eventDate",
},
Expand All @@ -2694,6 +2695,45 @@ def test_object_ttl_config_to_dict(ttl_config: _ObjectTTLConfig, expected: dict)
assert ttl_config.to_dict() == expected


TEST_OBJECT_TTL_ROUNDTRIP_PARAMETERS = [
# _creationTimeUnix round-trip
{
"objectTtlConfig": {
"enabled": True,
"defaultTtl": 60,
"deleteOn": "_creationTimeUnix",
"filterExpiredObjects": True,
}
},
# _lastUpdateTimeUnix round-trip
{
"objectTtlConfig": {
"enabled": True,
"defaultTtl": 3600,
"deleteOn": "_lastUpdateTimeUnix",
"filterExpiredObjects": True,
}
},
# custom date property round-trip
{
"objectTtlConfig": {
"enabled": True,
"defaultTtl": 123,
"deleteOn": "reference_date",
"filterExpiredObjects": True,
}
},
]


@pytest.mark.parametrize("schema", TEST_OBJECT_TTL_ROUNDTRIP_PARAMETERS)
def test_object_ttl_config_roundtrip(schema: dict) -> None:
"""Test that deserializing an objectTtlConfig and calling to_dict() produces the original dict."""
ttl_config = _get_object_ttl_config(schema)
assert ttl_config is not None
assert ttl_config.to_dict() == schema["objectTtlConfig"]


def test_nested_property_with_id_name_is_allowed() -> None:
"""A nested property named 'id' must not raise — only top-level 'id' is reserved."""
prop = Property(
Expand Down
16 changes: 16 additions & 0 deletions weaviate/collections/classes/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1938,6 +1938,22 @@ class _ObjectTTLConfig(_ConfigBase):
filter_expired_objects: bool
delete_on: Union[str, Literal["updateTime"], Literal["creationTime"]]

def to_dict(self) -> dict:
delete_on = self.delete_on
if delete_on == "creationTime":
delete_on = "_creationTimeUnix"
elif delete_on == "updateTime":
delete_on = "_lastUpdateTimeUnix"

Comment thread
dudanogueira marked this conversation as resolved.
out: dict = {
"enabled": self.enabled,
"filterExpiredObjects": self.filter_expired_objects,
"deleteOn": delete_on,
}
if self.time_to_live is not None:
out["defaultTtl"] = int(self.time_to_live.total_seconds())
return out


ObjectTTLConfig = _ObjectTTLConfig

Expand Down
Loading