diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5b5be9d..597b163 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,12 @@ Changelog unreleased ++++++++++ +Bug fixes: + +* Don't attach a length validator to Python ``Enum`` columns. Validators run + after deserialization, so ``len()`` was called on the enum member + (:issue:`673`). + Other changes: * Drop support for marshmallow 3, which is EOL. diff --git a/src/marshmallow_sqlalchemy/convert.py b/src/marshmallow_sqlalchemy/convert.py index 2b7c670..c97f1c9 100644 --- a/src/marshmallow_sqlalchemy/convert.py +++ b/src/marshmallow_sqlalchemy/convert.py @@ -445,7 +445,11 @@ def _add_column_kwargs(self, kwargs: dict[str, Any], column: sa.Column) -> None: except (AttributeError, NotImplementedError): python_type = None if not python_type or not issubclass(python_type, uuid.UUID): - kwargs["validate"].append(validate.Length(max=column_length)) + # Enum members have no len(); the DB length is redundant + # once the value is deserialized to the enum class. + # https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues/673 + if getattr(column.type, "enum_class", None) is None: + kwargs["validate"].append(validate.Length(max=column_length)) if getattr(column.type, "asdecimal", False): kwargs["places"] = getattr(column.type, "scale", None) diff --git a/tests/test_conversion.py b/tests/test_conversion.py index dd467cc..ca2ff3c 100644 --- a/tests/test_conversion.py +++ b/tests/test_conversion.py @@ -82,7 +82,9 @@ def test_enum_with_class_converted_to_enum_field(self, models): field = fields_["level_with_enum_class"] assert type(field) is fields.Enum assert contains_validator(field, validate.OneOf) is False + assert contains_validator(field, validate.Length) is False assert field.enum is CourseLevel + assert field.deserialize("PRIMARY") is CourseLevel.PRIMARY def test_many_to_many_relationship(self, models): student_fields = fields_for_model(models.Student, include_relationships=True)