From 097ce0563e2e67881b3733d28607fc958a986c63 Mon Sep 17 00:00:00 2001 From: mameikagou Date: Fri, 21 Aug 2026 04:59:31 +0800 Subject: [PATCH 1/3] fix: preserve top-level field type params Signed-off-by: mameikagou --- pymilvus/orm/schema.py | 3 ++ tests/unit/orm/test_schema.py | 67 +++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/pymilvus/orm/schema.py b/pymilvus/orm/schema.py index 30b7ad04e..908d6aafa 100644 --- a/pymilvus/orm/schema.py +++ b/pymilvus/orm/schema.py @@ -657,6 +657,9 @@ def _parse_type_params(self): def construct_from_dict(cls, raw: Dict): kwargs = {} kwargs.update(raw.get("params", {})) + for key in ("max_length", "dim"): + if key not in kwargs and raw.get(key) is not None: + kwargs[key] = raw[key] kwargs["is_primary"] = raw.get("is_primary", False) if raw.get("auto_id") is not None: kwargs["auto_id"] = raw.get("auto_id") diff --git a/tests/unit/orm/test_schema.py b/tests/unit/orm/test_schema.py index bedef1ec4..bd684cbf9 100644 --- a/tests/unit/orm/test_schema.py +++ b/tests/unit/orm/test_schema.py @@ -337,6 +337,73 @@ def test_construct_from_dict_roundtrip(self, raw_dict): assert result["name"] == raw_dict["name"] assert result["type"] == raw_dict["type"] + def test_construct_from_dict_with_top_level_max_length(self): + raw_dict = { + "name": "text", + "type": DataType.VARCHAR, + "max_length": 256, + } + + field = FieldSchema.construct_from_dict(raw_dict) + + assert field.params == {"max_length": 256} + assert field.to_dict()["params"] == {"max_length": 256} + + def test_construct_from_dict_with_top_level_dim(self): + raw_dict = { + "name": "vec", + "type": DataType.FLOAT_VECTOR, + "dim": 128, + } + + field = FieldSchema.construct_from_dict(raw_dict) + + assert field.params == {"dim": 128} + assert field.to_dict()["params"] == {"dim": 128} + + def test_construct_from_dict_ignores_none_top_level_param(self): + raw_dict = { + "name": "vec", + "type": DataType.FLOAT_VECTOR, + "dim": None, + } + + field = FieldSchema.construct_from_dict(raw_dict) + + assert field.params == {} + assert "params" not in field.to_dict() + + @pytest.mark.parametrize( + "raw_dict,expected_params", + [ + pytest.param( + { + "name": "text", + "type": DataType.VARCHAR, + "params": {"max_length": 256}, + "max_length": 512, + }, + {"max_length": 256}, + id="max_length", + ), + pytest.param( + { + "name": "vec", + "type": DataType.FLOAT_VECTOR, + "params": {"dim": 128}, + "dim": 256, + }, + {"dim": 128}, + id="dim", + ), + ], + ) + def test_construct_from_dict_nested_params_take_precedence(self, raw_dict, expected_params): + field = FieldSchema.construct_from_dict(raw_dict) + + assert field.params == expected_params + assert field.to_dict()["params"] == expected_params + class TestFieldSchemaDeepCopy: """Tests for FieldSchema __deepcopy__ method.""" From 26310b7a7170be4974832f28d39de39698c5153c Mon Sep 17 00:00:00 2001 From: mameikagou Date: Fri, 21 Aug 2026 23:13:24 +0800 Subject: [PATCH 2/3] fix: preserve all common field type params Signed-off-by: mameikagou --- pymilvus/orm/schema.py | 2 +- tests/unit/orm/test_schema.py | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/pymilvus/orm/schema.py b/pymilvus/orm/schema.py index 908d6aafa..ebfa8a0b5 100644 --- a/pymilvus/orm/schema.py +++ b/pymilvus/orm/schema.py @@ -657,7 +657,7 @@ def _parse_type_params(self): def construct_from_dict(cls, raw: Dict): kwargs = {} kwargs.update(raw.get("params", {})) - for key in ("max_length", "dim"): + for key in COMMON_TYPE_PARAMS: if key not in kwargs and raw.get(key) is not None: kwargs[key] = raw[key] kwargs["is_primary"] = raw.get("is_primary", False) diff --git a/tests/unit/orm/test_schema.py b/tests/unit/orm/test_schema.py index bd684cbf9..7c14db081 100644 --- a/tests/unit/orm/test_schema.py +++ b/tests/unit/orm/test_schema.py @@ -361,6 +361,55 @@ def test_construct_from_dict_with_top_level_dim(self): assert field.params == {"dim": 128} assert field.to_dict()["params"] == {"dim": 128} + @pytest.mark.parametrize( + "raw_dict,expected_params", + [ + pytest.param( + { + "name": "tags", + "type": DataType.ARRAY, + "element_type": DataType.VARCHAR, + "max_capacity": 100, + }, + {"max_capacity": 100}, + id="max_capacity", + ), + pytest.param( + { + "name": "text", + "type": DataType.TEXT, + "enable_match": True, + "enable_analyzer": False, + }, + {"enable_match": True, "enable_analyzer": False}, + id="analyzer_flags", + ), + pytest.param( + { + "name": "text", + "type": DataType.TEXT, + "analyzer_params": {"type": "standard"}, + }, + {"analyzer_params": '{"type":"standard"}'}, + id="analyzer_params", + ), + pytest.param( + { + "name": "text", + "type": DataType.TEXT, + "multi_analyzer_params": {"analyzers": [{"type": "standard"}]}, + }, + {"multi_analyzer_params": '{"analyzers":[{"type":"standard"}]}'}, + id="multi_analyzer_params", + ), + ], + ) + def test_construct_from_dict_with_top_level_common_type_params(self, raw_dict, expected_params): + field = FieldSchema.construct_from_dict(raw_dict) + + assert field.params == expected_params + assert field.to_dict()["params"] == expected_params + def test_construct_from_dict_ignores_none_top_level_param(self): raw_dict = { "name": "vec", From 4006b1cc226e45fcc28579680a719cb7f75abd15 Mon Sep 17 00:00:00 2001 From: mameikagou Date: Thu, 27 Aug 2026 14:58:24 +0800 Subject: [PATCH 3/3] fix(orm): preserve mmap and warmup field parameters --- pymilvus/orm/schema.py | 2 +- tests/unit/orm/test_schema.py | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/pymilvus/orm/schema.py b/pymilvus/orm/schema.py index ebfa8a0b5..5576dbf39 100644 --- a/pymilvus/orm/schema.py +++ b/pymilvus/orm/schema.py @@ -657,7 +657,7 @@ def _parse_type_params(self): def construct_from_dict(cls, raw: Dict): kwargs = {} kwargs.update(raw.get("params", {})) - for key in COMMON_TYPE_PARAMS: + for key in (*COMMON_TYPE_PARAMS, "mmap_enabled", "warmup"): if key not in kwargs and raw.get(key) is not None: kwargs[key] = raw[key] kwargs["is_primary"] = raw.get("is_primary", False) diff --git a/tests/unit/orm/test_schema.py b/tests/unit/orm/test_schema.py index 7c14db081..a30c4d486 100644 --- a/tests/unit/orm/test_schema.py +++ b/tests/unit/orm/test_schema.py @@ -402,6 +402,24 @@ def test_construct_from_dict_with_top_level_dim(self): {"multi_analyzer_params": '{"analyzers":[{"type":"standard"}]}'}, id="multi_analyzer_params", ), + pytest.param( + { + "name": "vec", + "type": DataType.FLOAT_VECTOR, + "mmap_enabled": True, + }, + {"mmap_enabled": True}, + id="mmap_enabled", + ), + pytest.param( + { + "name": "vec", + "type": DataType.FLOAT_VECTOR, + "warmup": {"policy": "async"}, + }, + {"warmup": {"policy": "async"}}, + id="warmup", + ), ], ) def test_construct_from_dict_with_top_level_common_type_params(self, raw_dict, expected_params): @@ -445,6 +463,26 @@ def test_construct_from_dict_ignores_none_top_level_param(self): {"dim": 128}, id="dim", ), + pytest.param( + { + "name": "vec", + "type": DataType.FLOAT_VECTOR, + "params": {"mmap_enabled": True}, + "mmap_enabled": False, + }, + {"mmap_enabled": True}, + id="mmap_enabled", + ), + pytest.param( + { + "name": "vec", + "type": DataType.FLOAT_VECTOR, + "params": {"warmup": {"policy": "sync"}}, + "warmup": {"policy": "async"}, + }, + {"warmup": {"policy": "sync"}}, + id="warmup", + ), ], ) def test_construct_from_dict_nested_params_take_precedence(self, raw_dict, expected_params):