From: Mike Bayer Date: Tue, 27 Apr 2021 17:09:04 +0000 (-0400) Subject: have SchemaType inherit schema from metadata X-Git-Tag: rel_1_4_12~24^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=70c51bbe5e0c0f7feb4695b2a38140ec53282c27;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git have SchemaType inherit schema from metadata 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 --- diff --git a/doc/build/changelog/unreleased_14/6373.rst b/doc/build/changelog/unreleased_14/6373.rst new file mode 100644 index 0000000000..7f0dd7e1e8 --- /dev/null +++ b/doc/build/changelog/unreleased_14/6373.rst @@ -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`. diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py index 489594b851..024b9f01e7 100644 --- a/lib/sqlalchemy/sql/sqltypes.py +++ b/lib/sqlalchemy/sql/sqltypes.py @@ -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. diff --git a/test/dialect/postgresql/test_types.py b/test/dialect/postgresql/test_types.py index 811c51d19d..2f975e4a8b 100644 --- a/test/dialect/postgresql/test_types.py +++ b/test/dialect/postgresql/test_types.py @@ -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) diff --git a/test/sql/test_metadata.py b/test/sql/test_metadata.py index 25834ac766..90da508754 100644 --- a/test/sql/test_metadata.py +++ b/test/sql/test_metadata.py @@ -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)