diff options
-rw-r--r-- | doc/build/changelog/changelog_11.rst | 9 | ||||
-rw-r--r-- | doc/build/changelog/migration_11.rst | 15 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/postgresql/base.py | 38 | ||||
-rw-r--r-- | test/dialect/postgresql/test_reflection.py | 22 |
4 files changed, 81 insertions, 3 deletions
diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst index e1c8a654d..fe56c4cf3 100644 --- a/doc/build/changelog/changelog_11.rst +++ b/doc/build/changelog/changelog_11.rst @@ -61,6 +61,15 @@ batched. Pull request courtesy Tobias Sauerwein. .. change:: + :tags: feature, postgresql + :tickets: 3588 + + Added new parameter :paramref:`.PGInspector.get_view_names.include`, + allowing specification for what kinds of views should be returned. + Currently "plain" and "materialized" views are included. Pull + request courtesy Sebastian Bank. + + .. change:: :tags: feature, mssql The ``mssql_clustered`` flag available on :class:`.UniqueConstraint`, diff --git a/doc/build/changelog/migration_11.rst b/doc/build/changelog/migration_11.rst index c60b17af5..73483f3db 100644 --- a/doc/build/changelog/migration_11.rst +++ b/doc/build/changelog/migration_11.rst @@ -2167,6 +2167,21 @@ both within the method :meth:`.Inspector.get_check_constraints` as well as within :class:`.Table` reflection within the :attr:`.Table.constraints` collection. +"Plain" and "Materialized" views can be inspected separately +------------------------------------------------------------ + +The new argument :paramref:`.PGInspector.get_view_names.include` +allows specification of which sub-types of views should be returned:: + + from sqlalchemy import inspect + insp = inspect(engine) + + plain_views = insp.get_view_names(include='plain') + all_views = insp.get_view_names(include=('plain', 'materialized')) + +:ticket:`3588` + + Added tablespace option to Index -------------------------------- diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index d613aac92..ec20c4b7a 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -1557,6 +1557,24 @@ class PGInspector(reflection.Inspector): schema = schema or self.default_schema_name return self.dialect._get_foreign_table_names(self.bind, schema) + def get_view_names(self, schema=None, include=('plain', 'materialized')): + """Return all view names in `schema`. + + :param schema: Optional, retrieve names from a non-default schema. + For special quoting, use :class:`.quoted_name`. + + :param include: specify which types of views to return. Passed + as a string value (for a single type) or a tuple (for any number + of types). Defaults to ``('plain', 'materialized')``. + + .. versionadded:: 1.1 + + """ + + return self.dialect.get_view_names(self.bind, schema, + info_cache=self.info_cache, + include=include) + class CreateEnumType(schema._CreateDropBase): __visit_name__ = "create_enum_type" @@ -1958,11 +1976,27 @@ class PGDialect(default.DefaultDialect): return [name for name, in result] @reflection.cache - def get_view_names(self, connection, schema=None, **kw): + def get_view_names( + self, connection, schema=None, + include=('plain', 'materialized'), **kw): + + include_kind = {'plain': 'v', 'materialized': 'm'} + try: + kinds = [include_kind[i] for i in util.to_list(include)] + except KeyError: + raise ValueError( + "include %r unknown, needs to be a sequence containing " + "one or both of 'plain' and 'materialized'" % (include,)) + if not kinds: + raise ValueError( + "empty include, needs to be a sequence containing " + "one or both of 'plain' and 'materialized'") + result = connection.execute( sql.text("SELECT c.relname FROM pg_class c " "JOIN pg_namespace n ON n.oid = c.relnamespace " - "WHERE n.nspname = :schema AND c.relkind IN ('v', 'm')" + "WHERE n.nspname = :schema AND c.relkind IN (%s)" % + (", ".join("'%s'" % elem for elem in kinds)) ).columns(relname=sqltypes.Unicode), schema=schema if schema is not None else self.default_schema_name) return [name for name, in result] diff --git a/test/dialect/postgresql/test_reflection.py b/test/dialect/postgresql/test_reflection.py index a0f9dcd49..84aeef130 100644 --- a/test/dialect/postgresql/test_reflection.py +++ b/test/dialect/postgresql/test_reflection.py @@ -130,7 +130,27 @@ class MaterializedViewReflectionTest( def test_get_view_names(self): insp = inspect(testing.db) - eq_(set(insp.get_view_names()), set(['test_mview', 'test_regview'])) + eq_(set(insp.get_view_names()), set(['test_regview', 'test_mview'])) + + def test_get_view_names_plain(self): + insp = inspect(testing.db) + eq_( + set(insp.get_view_names(include=('plain',))), + set(['test_regview'])) + + def test_get_view_names_plain_string(self): + insp = inspect(testing.db) + eq_(set(insp.get_view_names(include='plain')), set(['test_regview'])) + + def test_get_view_names_materialized(self): + insp = inspect(testing.db) + eq_( + set(insp.get_view_names(include=('materialized',))), + set(['test_mview'])) + + def test_get_view_names_empty(self): + insp = inspect(testing.db) + assert_raises(ValueError, insp.get_view_names, include=()) def test_get_view_definition(self): insp = inspect(testing.db) |