]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Allow using Enum with length=None
authorEugene Toder <eltoder@gmail.com>
Tue, 22 Aug 2023 17:54:02 +0000 (13:54 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 23 Aug 2023 15:34:09 +0000 (11:34 -0400)
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

doc/build/changelog/unreleased_20/10269.rst [new file with mode: 0644]
lib/sqlalchemy/sql/sqltypes.py
test/sql/test_types.py

diff --git a/doc/build/changelog/unreleased_20/10269.rst b/doc/build/changelog/unreleased_20/10269.rst
new file mode 100644 (file)
index 0000000..615c1a1
--- /dev/null
@@ -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.
+
index 2ed4c8b2090fbf9557658c89f4cb4bd25608f843..fe6386f22e456c137dfea529287ba6df79612c38 100644 (file)
@@ -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
index b980d75e8c368b52aaf951b9f035d7211af94da3..eb91d9c4cdf7b551a3d7545d0bb627231f2f5a76 100644 (file)
@@ -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