SVS-VAMANA `compression` does not survive `IndexSchema.to_dict()`, breaking YAML round-trips and migration planning

オープン 初心者向け
#808 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 5 日以内に返信

@Bhavy-Ranka がすでに取り組んでいます。

2026年10月30日 から。

  • #809 @Bhavy-Ranka による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
78/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python
領域
backend

調査の方向性

redisvl/schema/fields.py の CompressionType と BaseVectorFieldAttributes から始め、次に redisvl/utils/utils.py の model_to_dict を読んでください。これは enum 値を小文字に変換します。大文字と小文字を区別しない enum 検索を追加し、次に IndexSchema.to_yaml()/from_yaml() の YAML ラウンドトリップ経路と、issue で示されている MigrationPlanner.merge_patch() 経路を確認してください。完了条件は、すべての圧縮値が to_yaml() の後に from_yaml() を通過し、merge_patch() が既存の圧縮ベクトルフィールドで動作し、正確な大文字と小文字の入力が FT.CREATE の正規値を引き続き生成することです。

索引モデルが issue の本文から書いたものです。

説明

Summary

IndexSchema.to_dict() writes an SVS-VAMANA field's compression in lower case, but IndexSchema.from_dict() accepts only the exact-case value, so a schema with compression cannot be read back from its own output. to_yaml() followed by from_yaml() fails for every CompressionType, and MigrationPlanner.merge_patch() fails for any index that already uses compression, even when the patch does not touch the vector field.

Reproduction

Measured on main at 6a81e13b with Python 3.13.9:

from redisvl.schema import IndexSchema

schema = IndexSchema.from_dict({
    "index": {"name": "a", "prefix": "a"},
    "fields": [{
        "name": "v",
        "type": "vector",
        "attrs": {"algorithm": "svs-vamana", "dims": 8, "compression": "LVQ8"},
    }],
})

schema.to_dict()["fields"][0]["attrs"]["compression"]  # 'lvq8'

schema.to_yaml("schema.yaml")
IndexSchema.from_yaml("schema.yaml")
# ValidationError: attrs.compression
#   Input should be 'LVQ4', 'LVQ4x4', 'LVQ4x8', 'LVQ8', 'LeanVec4x8' or 'LeanVec8x8'
#   [type=enum, input_value='lvq8', input_type=str]

All six values fail the same way: LVQ4, LVQ4x4, LVQ4x8, LVQ8, LeanVec4x8 and LeanVec8x8.

The migration planner hits the same error. Adding a numeric field to an index whose vector field uses LVQ8 raises it from MigrationPlanner().merge_patch(source_schema, patch), because merge_patch rebuilds the target schema with IndexSchema.from_dict(source_schema.to_dict()). AsyncMigrationPlanner calls the same merge_patch. Post-migration validation should fail the same way, since redisvl/migration/validation.py passes target_index.schema.to_dict() to canonicalize_schema, which calls IndexSchema.from_dict() on it; that follows from the code and has not been reproduced.

Cause

model_to_dict in redisvl/utils/utils.py serialises every enum as item.value.lower(). That is harmless for algorithm, datatype and distance_metric, because BaseVectorFieldAttributes.uppercase_strings in redisvl/schema/fields.py upper-cases them on input. compression has no such validator, and its values are mixed case, so the lower-cased output no longer matches any member.

Proposed fix

Make CompressionType accept its values case-insensitively, with a _missing_ classmethod that returns the member whose value matches ignoring case. Checked in isolation with pydantic 2.13: a model field typed with such an enum accepts "lvq8" and "LeanVec4x8" and still rejects unknown values. That keeps to_dict() output in the same lower-case convention as the other vector attributes, and it also loads YAML files that to_yaml() has already written in lower case, which a fix confined to the output side would leave unreadable. The case mapping in redisvl/migration/wizard.py, which exists to turn user input into the exact member value, can then be simplified.

Acceptance

  • IndexSchema.from_yaml() loads the output of to_yaml() for every CompressionType, with a regression test that fails before the fix.
  • MigrationPlanner.merge_patch() succeeds for a source index that uses compression, with a regression test.
  • Explicit exact-case values such as "LeanVec4x8" continue to work, and FT.CREATE still sends the canonical value.
主要言語
Python
スター
432
フォーク
116
平均マージ
8日 1時間
マージ済み PR(30日)
29

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

redis/redis-vl-python のほかの issue

redis/redis-vl-python の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。