]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
have SchemaType inherit schema from metadata
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 27 Apr 2021 17:09:04 +0000 (13:09 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 27 Apr 2021 17:13:52 +0000 (13:13 -0400)
Fixed very old issue where the :class:`_types.Enum` datatype would not
inherit the :paramref:`_schema.MetaData.schema` parameter of a
:class:`_schema.MetaData` object when that object were passed to the
:class:`_types.Enum` using :paramref:`_types.Enum.metadata`.

Fixes: #6373
Change-Id: Ie77d5e8cbc0bd7bfd0039fb60a4a0bde2df58ca9

doc/build/changelog/unreleased_14/6373.rst [new file with mode: 0644]
lib/sqlalchemy/sql/sqltypes.py
test/dialect/postgresql/test_types.py
test/sql/test_metadata.py

diff --git a/doc/build/changelog/unreleased_14/6373.rst b/doc/build/changelog/unreleased_14/6373.rst
new file mode 100644 (file)
index 0000000..7f0dd7e
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, postgresql
+    :tickets: 6373
+
+    Fixed very old issue where the :class:`_types.Enum` datatype would not
+    inherit the :paramref:`_schema.MetaData.schema` parameter of a
+    :class:`_schema.MetaData` object when that object were passed to the
+    :class:`_types.Enum` using :paramref:`_types.Enum.metadata`.
index 489594b85172f7904f4aa34389695ac5dceeaf37..024b9f01e72b976a3b9cda3542d2487b06bd5728 100644 (file)
@@ -1105,6 +1105,8 @@ class SchemaType(SchemaEventTarget):
     def _set_table(self, column, table):
         if self.inherit_schema:
             self.schema = table.schema
+        elif self.metadata and self.schema is None and self.metadata.schema:
+            self.schema = self.metadata.schema
 
         if not self._create_events:
             return
@@ -1365,6 +1367,16 @@ class Enum(Emulated, String, SchemaType):
            only dropped when ``drop_all()`` is called for that ``Table``
            object's metadata, however.
 
+           The value of the :paramref:`_schema.MetaData.schema` parameter of
+           the :class:`_schema.MetaData` object, if set, will be used as the
+           default value of the :paramref:`_types.Enum.schema` on this object
+           if an explicit value is not otherwise supplied.
+
+           .. versionchanged:: 1.4.12 :class:`_types.Enum` inherits the
+              :paramref:`_schema.MetaData.schema` parameter of the
+              :class:`_schema.MetaData` object if present, when passed using
+              the :paramref:`_types.Enum.metadata` parameter.
+
         :param name: The name of this type. This is required for PostgreSQL
            and any future supported database which requires an explicitly
            named type, or an explicitly named constraint in order to generate
@@ -1388,12 +1400,22 @@ class Enum(Emulated, String, SchemaType):
            this parameter specifies the named schema in which the type is
            present.
 
-           .. note::
+           If not present, the schema name will be taken from the
+           :class:`_schema.MetaData` collection if passed as
+           :paramref:`_types.Enum.metadata`, for a :class:`_schema.MetaData`
+           that includes the :paramref:`_schema.MetaData.schema` parameter.
+
+           .. versionchanged:: 1.4.12 :class:`_types.Enum` inherits the
+              :paramref:`_schema.MetaData.schema` parameter of the
+              :class:`_schema.MetaData` object if present, when passed using
+              the :paramref:`_types.Enum.metadata` parameter.
+
+           Otherwise, if the :paramref:`_types.Enum.inherit_schema` flag is set
+           to ``True``, the schema will be inherited from the associated
+           :class:`_schema.Table` object if any; when
+           :paramref:`_types.Enum.inherit_schema` is at its default of
+           ``False``, the owning table's schema is **not** used.
 
-                The ``schema`` of the :class:`.Enum` type does not
-                by default make use of the ``schema`` established on the
-                owning :class:`_schema.Table`.  If this behavior is desired,
-                set the ``inherit_schema`` flag to ``True``.
 
         :param quote: Set explicit quoting preferences for the type's name.
 
index 811c51d19d31b68a2ecf9e79ffb70cdf6eeafffd..2f975e4a8ba57a6bbaa0a20fdcdd6d40927440f3 100644 (file)
@@ -224,6 +224,70 @@ class EnumTest(fixtures.TestBase, AssertsExecutionResults):
         ]
         t1.drop(conn, checkfirst=True)
 
+    @testing.combinations(
+        ("local_schema",),
+        ("metadata_schema_only",),
+        ("inherit_table_schema",),
+        ("override_metadata_schema",),
+        argnames="test_case",
+    )
+    @testing.requires.schemas
+    def test_schema_inheritance(self, test_case, metadata, connection):
+        """test #6373"""
+
+        metadata.schema = testing.config.test_schema
+
+        if test_case == "metadata_schema_only":
+            enum = Enum(
+                "four", "five", "six", metadata=metadata, name="myenum"
+            )
+            assert_schema = testing.config.test_schema
+        elif test_case == "override_metadata_schema":
+            enum = Enum(
+                "four",
+                "five",
+                "six",
+                metadata=metadata,
+                schema=testing.config.test_schema_2,
+                name="myenum",
+            )
+            assert_schema = testing.config.test_schema_2
+        elif test_case == "inherit_table_schema":
+            enum = Enum(
+                "four",
+                "five",
+                "six",
+                metadata=metadata,
+                inherit_schema=True,
+                name="myenum",
+            )
+            assert_schema = testing.config.test_schema_2
+        elif test_case == "local_schema":
+            enum = Enum("four", "five", "six", name="myenum")
+            assert_schema = testing.config.db.dialect.default_schema_name
+
+        Table(
+            "t",
+            metadata,
+            Column("data", enum),
+            schema=testing.config.test_schema_2,
+        )
+
+        metadata.create_all(connection)
+
+        eq_(
+            inspect(connection).get_enums(schema=assert_schema),
+            [
+                {
+                    "labels": ["four", "five", "six"],
+                    "name": "myenum",
+                    "schema": assert_schema,
+                    "visible": assert_schema
+                    == testing.config.db.dialect.default_schema_name,
+                }
+            ],
+        )
+
     def test_name_required(self, metadata, connection):
         etype = Enum("four", "five", "six", metadata=metadata)
         assert_raises(exc.CompileError, etype.create, connection)
index 25834ac766dc213b033a7955be841394f0f39663..90da5087543df13cb4890a702db44f6cdc427a05 100644 (file)
@@ -2186,6 +2186,27 @@ class SchemaTypeTest(fixtures.TestBase):
         t1 = Table("x", m, Column("y", type_), schema="z")
         eq_(t1.c.y.type.schema, "q")
 
+    def test_inherit_schema_from_metadata(self):
+        """test #6373"""
+        m = MetaData(schema="q")
+        type_ = self.MyType(metadata=m)
+        t1 = Table("x", m, Column("y", type_), schema="z")
+        eq_(t1.c.y.type.schema, "q")
+
+    def test_inherit_schema_from_table_override_metadata(self):
+        """test #6373"""
+        m = MetaData(schema="q")
+        type_ = self.MyType(metadata=m, inherit_schema=True)
+        t1 = Table("x", m, Column("y", type_), schema="z")
+        eq_(t1.c.y.type.schema, "z")
+
+    def test_inherit_schema_from_metadata_override_explicit(self):
+        """test #6373"""
+        m = MetaData(schema="q")
+        type_ = self.MyType(schema="e", metadata=m)
+        t1 = Table("x", m, Column("y", type_), schema="z")
+        eq_(t1.c.y.type.schema, "e")
+
     def test_inherit_schema(self):
         m = MetaData()
         type_ = self.MyType(schema="q", inherit_schema=True)