From: Eugene Toder Date: Tue, 22 Aug 2023 17:54:02 +0000 (-0400) Subject: Allow using Enum with length=None X-Git-Tag: rel_2_0_21~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7cf836241aa72494b42b645a3ddec04b0a6e6061;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Allow using Enum with length=None Adjusted the :class:`_types.Enum` datatype to accept an argument of ``None`` for the :paramref:`_types.Enum.length` parameter, resulting in a VARCHAR or other textual type with no length in the resulting DDL. This allows for new elements of any length to be added to the type after it exists in the schema. Pull request courtesy Eugene Toder. Fixes: #10269 Closes: #10274 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/10274 Pull-request-sha: 651afaaea76c1ec868402cdd7106ec8b2de76254 Change-Id: I374ae9e5fa63da21a4cc87e323ce1a54acd6e39b --- diff --git a/doc/build/changelog/unreleased_20/10269.rst b/doc/build/changelog/unreleased_20/10269.rst new file mode 100644 index 0000000000..615c1a1619 --- /dev/null +++ b/doc/build/changelog/unreleased_20/10269.rst @@ -0,0 +1,10 @@ +.. change:: + :tags: usecase, sql + :tickets: 10269 + + Adjusted the :class:`_types.Enum` datatype to accept an argument of + ``None`` for the :paramref:`_types.Enum.length` parameter, resulting in a + VARCHAR or other textual type with no length in the resulting DDL. This + allows for new elements of any length to be added to the type after it + exists in the schema. Pull request courtesy Eugene Toder. + diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py index 2ed4c8b209..fe6386f22e 100644 --- a/lib/sqlalchemy/sql/sqltypes.py +++ b/lib/sqlalchemy/sql/sqltypes.py @@ -1451,7 +1451,11 @@ class Enum(String, SchemaType, Emulated, TypeEngine[Union[str, enum.Enum]]): self._default_length = length = 0 if length_arg is not NO_ARG: - if not _disable_warnings and length_arg < length: + if ( + not _disable_warnings + and length_arg is not None + and length_arg < length + ): raise ValueError( "When provided, length must be larger or equal" " than the length of the longest enum value. %s < %s" @@ -1658,14 +1662,14 @@ class Enum(String, SchemaType, Emulated, TypeEngine[Union[str, enum.Enum]]): ) def as_generic(self, allow_nulltype=False): - if hasattr(self, "enums"): + try: args = self.enums - else: + except AttributeError: raise NotImplementedError( "TypeEngine.as_generic() heuristic " "is undefined for types that inherit Enum but do not have " "an `enums` attribute." - ) + ) from None return util.constructor_copy( self, self._generic_type_affinity, *args, _disable_warnings=True diff --git a/test/sql/test_types.py b/test/sql/test_types.py index b980d75e8c..eb91d9c4cd 100644 --- a/test/sql/test_types.py +++ b/test/sql/test_types.py @@ -2723,6 +2723,12 @@ class EnumTest(AssertsCompiledSQL, fixtures.TablesTest): e = Enum("x", "y", "long", native_enum=False, length=42) eq_(e.length, 42) + def test_none_length_non_native(self): + e = Enum("x", "y", native_enum=False, length=None) + eq_(e.length, None) + eq_(repr(e), "Enum('x', 'y', native_enum=False, length=None)") + self.assert_compile(e, "VARCHAR", dialect="default") + def test_omit_aliases(self, connection): table0 = self.tables["stdlib_enum_table"] type0 = table0.c.someenum.type