Connector
PostgreSQL, Greenplum
Feature area
Metadata ingestion
Describe the bug
Materialized views are never ingested during DatabaseMetadata ingestion, even with includeViews: true. They are not misclassified as View — they are absent from the catalogue entirely, and the run reports success with no warning and no filtered-entity record.
Neither of the two object-enumeration paths reaches them:
query_table_names_and_types() is overridden by both connectors (postgres/metadata.py, greenplum/metadata.py) and filters pg_class.relkind IN ('r', 'p', 'f'), which excludes 'm'.
query_view_names_and_types() is overridden by neither, so it falls back to the default in common_db_source.py, which calls Inspector.get_view_names().
Per the SQLAlchemy 2.0 reflection docs, dialects that previously included materialized views in get_view_names() — PostgreSQL among them — no longer do; callers must use Inspector.get_materialized_view_names(), which no connector calls. ingestion/setup.py pins sqlalchemy>=2.0.0,<3, so every supported installation is on the split reflection API and the default view path can no longer see materialized views.
The remaining pieces are already in place: TableType.MaterializedView exists in the entity schema, and get_view_definition for Greenplum already runs GREENPLUM_VIEW_DEFINITIONS, whose filter is relkind IN ('v', 'm'). Only the enumeration is missing.
To Reproduce
- In PostgreSQL or Greenplum, create a schema with one ordinary table, one plain view and one materialized view:
CREATE SCHEMA mv_repro;
CREATE TABLE mv_repro.base_table (id int, amount numeric);
CREATE VIEW mv_repro.plain_view AS
SELECT id, amount FROM mv_repro.base_table;
CREATE MATERIALIZED VIEW mv_repro.mat_view AS
SELECT id, sum(amount) AS total FROM mv_repro.base_table GROUP BY 1;
- Confirm the ingestion user can see the materialized view:
SELECT matviewname FROM pg_matviews WHERE schemaname = 'mv_repro';
-- mat_view
-
Run metadata ingestion for that service with includeTables: true, includeViews: true and schemaFilterPattern limited to mv_repro
-
List what was ingested into that schema:
curl -H "Authorization: Bearer $JWT" \
"$OM/api/v1/tables?databaseSchema=<service>.<database>.mv_repro&limit=100"
Result: base_table and plain_view are returned, mat_view is not. It is not
reclassified as View — it does not exist as an entity at all. Searching the index for
tableType:MaterializedView returns 0 hits. The ingestion run reports success and emits
no warning and no filtered-entity record for it.
Expected behavior
Materialized views should be ingested as:
tableType=MaterializedView
when includeViews=true, including columns, schemaDefinition and view lineage.
Connection / ingestion config
Logs
OS
Linux
Python version
3.10.20
OpenMetadata version
1.13.0
OpenMetadata Ingestion package version
1.13.0
Additional context
Suggested implementation
Override query_view_names_and_types() for PostgreSQL/Greenplum and combine:
- Inspector.get_view_names() -> TableType.View
- Inspector.get_materialized_view_names() -> TableType.MaterializedView
This keeps materialized views under the includeViews flag, where they belong.
Please avoid the shortcut of adding m to the table-discovery queries: that puts materialized views on the table path, where includeViews no longer applies, and it also needs m added to RELKIND_MAP in common_pg_mappings.py, which currently maps only r, p, f and v.
Pre-submission checklist
Connector
PostgreSQL, Greenplum
Feature area
Metadata ingestion
Describe the bug
Materialized views are never ingested during
DatabaseMetadataingestion, even withincludeViews: true. They are not misclassified asView— they are absent from the catalogue entirely, and the run reports success with no warning and no filtered-entity record.Neither of the two object-enumeration paths reaches them:
query_table_names_and_types()is overridden by both connectors (postgres/metadata.py,greenplum/metadata.py) and filterspg_class.relkind IN ('r', 'p', 'f'), which excludes'm'.query_view_names_and_types()is overridden by neither, so it falls back to the default incommon_db_source.py, which callsInspector.get_view_names().Per the SQLAlchemy 2.0 reflection docs, dialects that previously included materialized views in
get_view_names()— PostgreSQL among them — no longer do; callers must useInspector.get_materialized_view_names(), which no connector calls.ingestion/setup.pypinssqlalchemy>=2.0.0,<3, so every supported installation is on the split reflection API and the default view path can no longer see materialized views.The remaining pieces are already in place:
TableType.MaterializedViewexists in the entity schema, andget_view_definitionfor Greenplum already runsGREENPLUM_VIEW_DEFINITIONS, whose filter isrelkind IN ('v', 'm'). Only the enumeration is missing.To Reproduce
Run metadata ingestion for that service with
includeTables: true,includeViews: trueandschemaFilterPatternlimited tomv_reproList what was ingested into that schema:
Result:
base_tableandplain_vieware returned,mat_viewis not. It is notreclassified as
View— it does not exist as an entity at all. Searching the index fortableType:MaterializedViewreturns 0 hits. The ingestion run reports success and emitsno warning and no filtered-entity record for it.
Expected behavior
Materialized views should be ingested as:
when
includeViews=true, including columns, schemaDefinition and view lineage.Connection / ingestion config
Logs
OS
Linux
Python version
3.10.20
OpenMetadata version
1.13.0
OpenMetadata Ingestion package version
1.13.0
Additional context
Suggested implementation
Override query_view_names_and_types() for PostgreSQL/Greenplum and combine:
This keeps materialized views under the
includeViewsflag, where they belong.Please avoid the shortcut of adding
mto the table-discovery queries: that puts materialized views on the table path, whereincludeViewsno longer applies, and it also needsmadded toRELKIND_MAPincommon_pg_mappings.py, which currently maps onlyr,p,fandv.Pre-submission checklist