Заполнение n уровня PostgreSQL таблицы в python - PullRequest
1 голос
/ 17 июня 2020

Мне сложно продумать, как заполнить таблицу n-го уровня (в моем случае это 3 уровня), я использую python для извлечения данных из запроса, но я не уверен, как подойти к заполнению моей новой таблицы resources, поскольку ссылается на себя. Будем очень благодарны за любые отзывы о подходе!

После выполнения следующего запроса в моем python файле я получаю следующую таблицу

SELECT distinct c.table_catalog AS "Database", c.table_schema AS "Schema", c.table_name AS "Table"
FROM information_schema.columns c
WHERE c.table_schema != 'information_schema' AND c.table_schema != 'pg_catalog' AND c.table_schema != 'pg_internal' AND c.table_schema not like '% %'
ORDER BY c.table_schema, c.table_name;


Database  Schema            Table
____________________________________
dev       BigBangTheory     SomeTable1
dev       BigBangTheory     SomeTable2
dev       BigBangTheory     SomeTable3
dev       Walle             AnotherTable100
dev       Walle             AnotherTable200
dev       StarWars          SpaceTablexxx
dev       StarWars          SpaceTableyyy
stage     BigBangTheory     SomeTable1
stage     BigBangTheory     SomeTable2
stage     BigBangTheory     SomeTable3
stage     Walle             AnotherTable100
stage     Walle             AnotherTable200
stage     StarWars          SpaceTablexxx
stage     StarWars          SpaceTableyyy

И у меня есть еще одна таблица, которую я хочу заполнить, используя приведенные выше результаты. Таблица, которую я хочу заполнить, выглядит так:

CREATE TABLE IF NOT EXISTS resources
(
"id" SERIAL NOT NULL PRIMARY KEY,
"type" varchar(100) NOT NULL,             
"name" varchar(100) NOT NULL,    
"parent" int,
FOREIGN KEY (parent) REFERENCES resources (id)
);

, поэтому моя цель состоит в том, чтобы таблица resources выглядела так:

id      type         name                   parent
____________________________________________________
1       database     dev                    NULL
2       schema       BigBangTheory          1
3       table        SomeTable1             2
4       table        SomeTable2             2
5       table        SomeTable3             2
6       schema       Walle                  1
7       table        AnotherTable100        6
8       table        AnotherTable200        6
9       schema       StarWars               1
10      table        SpaceTablexxx          9
11      table        SpaceTableyyy          9

12      database     stage                  NULL
13      schema       BigBangTheory          12
14      table        SomeTable1             13
15      table        SomeTable2             13
16      table        SomeTable3             13
17      schema       Walle                  12
18      table        AnotherTable100        17
19      table        AnotherTable200        17
20      schema       StarWars               12
21      table        SpaceTablexxx          20
22      table        SpaceTableyyy          20

Заранее спасибо! Все отзывы приветствуются <3 </p>

1 Ответ

1 голос
/ 17 июня 2020

Для начала: вы можете получить нужную информацию непосредственно из information_schema.tables, а не information_schema.columns (в таблице всего одна строка, поэтому требуется distinct).

Затем: в Postgres, вы можете делать все, что хотите, в одном запросе, используя каскадные общие табличные выражения с предложением returning до insert операторов в Postgres. can

Logi c - это сначала вставлять верхние объекты (базы данных) и возвращать сгенерированные сериалы, затем вставлять схемы (используя сериалы базы данных) и, наконец, таблицы.

with 
    info as (
        select c.table_catalog, c.table_schema, c.table_name
        from information_schema.tables
        where 
            c.table_schema not in ('information_schema', 'pg_catalog', 'pg_internal')
            and c.table_schema not like '% %'
    ),
    dbs as (
        insert into resources (type, name)
        select distinct 'database', table_catalog 
        from info
        returning id, name
    ),
    schemas as (
        insert into resources(type, name, parent)
        select distinct 'schema', i.table_schema, d.id
        from info i
        inner join dbs d on d.name = i.table_catalog
        returning id, name, parent
    )
insert into resources(type, name, parent)
select 'table', table_name, s.id
from info i
inner join schemas s on s.name = i.table_schema
inner join dbs d on d.id = s.parent and d.name = i.table_catalog

Обратите внимание, что последний insert присоединяется как к schemas, так и к dbs; это предназначено для правильной обработки "одноименных" таблиц, которые живут в разных схемах.

Здесь - это демонстрация (я использовал таблицу для отображения c результатов вашего первоначального запроса).

...