我在数据库中有一个视图,其中每个记录都有两列:源和从属。在source列中是数据库中表/视图的名称,它是在从属列中找到的视图名称的源。我想使用Python创建另一个表,当使用CASCADE删除其源表时,该表可用于重新创建视图。
我知道我可以在SQL中使用CTE来实现每个“级别”的依赖关系。但是,我必须对每个级别进行硬编码,并且我需要动态级别的数量,以适应数据库中实现的级别数量。例如,如果视图“ b”依赖于表“ a”,则有两个级别,我可以为这两个级别编写代码。但是,如果创建了视图“ c”(取决于视图“ b”),那么现在有3个级别,我需要知道添加的级别并将其添加到我的代码中。
答案 0 :(得分:0)
使用递归CTE,仅使用SQL即可获得所需的内容。为了进行可视化,我为您的示例添加了一个额外的层次。
--- set up
create table view_dependencies (source_view text, depends_on_view text);
insert into view_dependencies( source_view, depends_on_view)
values ('b','a'), ('c','b'), ('d','c');
select * from view_dependencies;
-- show dependencies
with RECURSIVE view_depends as (
select source_view, depends_on_view, 1 lev
from view_dependencies
where depends_on_view = 'a'
UNION ALL
select v.source_view, v.depends_on_view, lev+1
from view_dependencies v
join view_depends d on (v.depends_on_view = d.source_view))
SELECT * FROM view_depends;
-- extend the dependencies
insert into view_dependencies( source_view, depends_on_view)
values ('g','d');
-- run the show dependencies query again.
好吧,因为您使用的工具不允许递归CTE,所以我首先会看到它提供了传递原始SQL语句(或也许更新工具)的能力。但是,假设这也不可用,您可以在其周围包装一个函数,如下所示。
create or replace function view_dependent_tree(base_view text)
returns table (source_view text
,depends_on text
,lev integer
)
language plpgsql
as $$
begin
for source_view
,depends_on
,lev
in
with RECURSIVE view_depends as (
select d.source_view, d.depends_on_view, 1 lev
from view_dependencies d
where depends_on_view = base_view
UNION ALL
select v.source_view, v.depends_on_view,d.lev+1
from view_dependencies v
join view_depends d on (v.depends_on_view = d.source_view))
SELECT * FROM view_depends
loop
return next;
end loop;
return;
end;
$$ ;
select source_view, depends_on, lev from view_dependent_tree('a');
您是否已经提到无法使用递归CTE?好吧,这本来很好,但是这样做暗示了先验知识将是建议。我以为不是。不用担心。