Создайте дерево зависимостей вида базы данных для вида отдыха после CASCADE - PullRequest
0 голосов
/ 25 июня 2019

У меня есть представление в моей базе данных, где каждая запись имеет два столбца: исходный и зависимый. В столбце источника указывается имя таблицы / представления в базе данных, для которой оно является источником имени представления, найденного в зависимом столбце. Используя Python, я хотел бы создать другую таблицу, которую можно использовать для воссоздания представлений, когда их исходная таблица была удалена с помощью CASCADE.

Я знаю, что могу сделать это в SQL, используя CTE для каждого «уровня» зависимостей. Тем не менее, мне нужно жестко программировать для каждого уровня, и мне нужно, чтобы количество уровней было динамическим, в соответствии с количеством уровней, реализованных в базе данных. Например, если представление 'b' зависит от таблицы 'a', существует два уровня, и я могу кодировать эти 2 уровня. Но если создается представление 'c', зависящее от представления 'b', теперь есть 3 уровня, и мне нужно знать о добавленном уровне и добавить его в мой код.

1 Ответ

0 голосов
/ 25 июня 2019

Вы можете получить то, что вы хотите, только с помощью SQL, используя Recursive CTE. Для визуализации я добавил дополнительный уровень к вашему примеру.

--- 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.

Что ж, поскольку инструмент, который вы используете, не позволяет использовать Recursive 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? Ну, это было бы хорошо, но сделать это означало бы априорное знание, которое было бы предложением. Я предполагаю, что это не было; не переживать.

...