Postgresql 查找表或视图的从属对象 出身背景

Postgresql 查找表或视图的从属对象 出身背景,postgresql,metadata,Postgresql,Metadata,在PostgreSQL中删除或替换对象时,如果存在依赖项,则删除操作将失败,而不指定级联 问题 数据库返回的错误消息未列出依赖对象 示例解 查询可能类似于: SELECT * FROM information_schema i, pg_depend pd WHERE i.object_id = pd.object_id AND i.object_type = 'TABLE' AND i.object_schema = 'public' AND i.object_name = 't

在PostgreSQL中删除或替换对象时,如果存在依赖项,则删除操作将失败,而不指定级联

问题 数据库返回的错误消息未列出依赖对象

示例解 查询可能类似于:

SELECT * FROM information_schema i, pg_depend pd WHERE
  i.object_id = pd.object_id AND
  i.object_type = 'TABLE' AND
  i.object_schema = 'public' AND
  i.object_name = 'table_with_dependents';
目标不见了

相关的 问题 如何按名称和类型生成依赖对象列表?

简单的方法是:

BEGIN;
DROP TABLE tablename CASCADE;
DROP VIEW viewname CASCADE;
ROLLBACK;

建议的解决方案在我使用postgresql 9.1.4时不起作用

这起到了作用:

SELECT dependent_ns.nspname as dependent_schema
, dependent_view.relname as dependent_view 
, source_ns.nspname as source_schema
, source_table.relname as source_table
, pg_attribute.attname as column_name
FROM pg_depend 
JOIN pg_rewrite ON pg_depend.objid = pg_rewrite.oid 
JOIN pg_class as dependent_view ON pg_rewrite.ev_class = dependent_view.oid 
JOIN pg_class as source_table ON pg_depend.refobjid = source_table.oid 
JOIN pg_attribute ON pg_depend.refobjid = pg_attribute.attrelid 
    AND pg_depend.refobjsubid = pg_attribute.attnum 
JOIN pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace
JOIN pg_namespace source_ns ON source_ns.oid = source_table.relnamespace
WHERE 
source_ns.nspname = 'my_schema'
AND source_table.relname = 'my_table'
AND pg_attribute.attnum > 0 
AND pg_attribute.attname = 'my_column'
ORDER BY 1,2;

对于PostgreSQL 9.3及以后版本,请使用以下视图和函数显示任何用户对象依赖关系。我也更新了

pg_constraint包含数据库中的所有约束。您可以从所有外键约束中使用confrelid和conrelid列出依赖表的oid

查询如下所示


从pg_constraint中选择conrelid,conrelid,其中contype='f'

在查询中包括嵌套视图,如下所示:

WITH RECURSIVE view_deps AS (
SELECT DISTINCT dependent_ns.nspname as dependent_schema
, dependent_view.relname as dependent_view
, source_ns.nspname as source_schema
, source_table.relname as source_table
FROM pg_depend
JOIN pg_rewrite ON pg_depend.objid = pg_rewrite.oid
JOIN pg_class as dependent_view ON pg_rewrite.ev_class = dependent_view.oid
JOIN pg_class as source_table ON pg_depend.refobjid = source_table.oid
JOIN pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace
JOIN pg_namespace source_ns ON source_ns.oid = source_table.relnamespace
WHERE NOT (dependent_ns.nspname = source_ns.nspname AND dependent_view.relname = source_table.relname)
UNION
SELECT DISTINCT dependent_ns.nspname as dependent_schema
, dependent_view.relname as dependent_view
, source_ns.nspname as source_schema
, source_table.relname as source_table
FROM pg_depend
JOIN pg_rewrite ON pg_depend.objid = pg_rewrite.oid
JOIN pg_class as dependent_view ON pg_rewrite.ev_class = dependent_view.oid
JOIN pg_class as source_table ON pg_depend.refobjid = source_table.oid
JOIN pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace
JOIN pg_namespace source_ns ON source_ns.oid = source_table.relnamespace
INNER JOIN view_deps vd
    ON vd.dependent_schema = source_ns.nspname
    AND vd.dependent_view = source_table.relname
    AND NOT (dependent_ns.nspname = vd.dependent_schema AND dependent_view.relname = vd.dependent_view)
)

SELECT *
FROM view_deps
ORDER BY source_schema, source_table;
如果您关心特定的表属性,请将其添加到递归CTE的顶部:

JOIN pg_attribute ON pg_depend.refobjid = pg_attribute.attrelid 
    AND pg_depend.refobjsubid = pg_attribute.attnum 
...
WHERE 
source_ns.nspname = 'my_schema'
AND source_table.relname = 'my_table'
AND pg_attribute.attnum > 0 
AND pg_attribute.attname = 'my_column'

我相信有一个更好的方法涉及到pg_依赖和pg_类目录。运行psql-E,然后使用\d查看表,应该会向您显示psql用于确定依赖于什么的查询。我认为9.3+中不需要级联。当删除失败时,错误消息详细信息现在包括从属对象。如果要删除表,则需要包括表:开始;升降台fld_ovrd级联;回降;如果您可以显示dependee.relname的模式,那就太好了,因为这样您知道对象名,但不知道找到它的模式。由于不同,如果在不同的模式中有两个具有相同relname的对象,您会认为只有一个dependancy@prince要获取架构,请将ns.nspname添加到选择列表中,并将ns.oid=dependee.relnamespace上的pg_名称空间ns连接到FROM列表中,在Postgres 9.3+中,错误消息确实列出了依赖对象。@通配符:错误消息对于机器分析来说太脆弱。
JOIN pg_attribute ON pg_depend.refobjid = pg_attribute.attrelid 
    AND pg_depend.refobjsubid = pg_attribute.attnum 
...
WHERE 
source_ns.nspname = 'my_schema'
AND source_table.relname = 'my_table'
AND pg_attribute.attnum > 0 
AND pg_attribute.attname = 'my_column'