Как дублировать схемы в PostgreSQL
у меня есть база данных со схемой public
и schema_A
. Мне нужно создать новую схему schema_b
С той же структурой, что и schema_a
.
Я нашел функцию ниже, проблема в том, что она не копирует ограничения внешнего ключа.
CREATE OR REPLACE FUNCTION clone_schema(source_schema text, dest_schema text)
RETURNS void AS
$BODY$
DECLARE
object text;
buffer text;
default_ text;
column_ text;
BEGIN
EXECUTE 'CREATE SCHEMA ' || dest_schema ;
-- TODO: Find a way to make this sequence's owner is the correct table.
FOR object IN
SELECT sequence_name::text FROM information_schema.SEQUENCES WHERE sequence_schema = source_schema
LOOP
EXECUTE 'CREATE SEQUENCE ' || dest_schema || '.' || object;
END LOOP;
FOR object IN
SELECT table_name::text FROM information_schema.TABLES WHERE table_schema = source_schema
LOOP
buffer := dest_schema || '.' || object;
EXECUTE 'CREATE TABLE ' || buffer || ' (LIKE ' || source_schema || '.' || object || ' INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING DEFAULTS)';
FOR column_, default_ IN
SELECT column_name::text, REPLACE(column_default::text, source_schema, dest_schema) FROM information_schema.COLUMNS WHERE table_schema = dest_schema AND table_name = object AND column_default LIKE 'nextval(%' || source_schema || '%::regclass)'
LOOP
EXECUTE 'ALTER TABLE ' || buffer || ' ALTER COLUMN ' || column_ || ' SET DEFAULT ' || default_;
END LOOP;
END LOOP;
END;
$BODY$ LANGUAGE plpgsql
как я могу клонировать/копировать schema_A
С ограничениями внешнего ключа?
4 ответов
вероятно, вы можете сделать это из командной строки без использования файлов:
pg_dump -U user --schema='fromschema' database | sed 's/fromschmea/toschema/g' | psql -U user -d database
Примечание что это ищет и заменяет все вхождения строки, которая является вашим именем схемы, так что это может повлиять на ваши данные.
Я хотел бы использовать pg_dump
сбросить схему без данных:
-s --schema-only
свалка только определения объектов (схема), а не данные.
эта опция является обратной
--data-only
. Он похож, но по историческим причинам не идентичен, указывая--section=pre-data --section=post-data
.(не путайте это с
--schema
опция, которая использует слово "схема" в другом значении.)чтобы исключить табличные данные только для подмножества таблиц в базе данных см.
--exclude-table-data
.
pg_dump $DB -p $PORT -n $SCHEMA -s -f filename.pgsql
затем переименуйте схему в дампе (search & replace) и восстановите ее с помощью psql
.
psql $DB -f filename.pgsql
ограничения внешнего ключа ссылки на таблицы в другое схемы копируются, чтобы указать на ту же схему.
Ссылки на таблицы в то же самое схема указывает на соответствующие таблицы в скопированной схеме.
немного поздно на вечеринку, но некоторые sql здесь могут помочь вам на вашем пути:
получить схему oid:
namespace_id = SELECT oid
FROM pg_namespace
WHERE nspname = '<schema name>';
получить OID таблицы:
table_id = SELECT relfilenode
FROM pg_class
WHERE relnamespace = '<namespace_id>' AND relname = '<table_name>'
сделать ограничения внешнего ключа:
SELECT con.conname, pg_catalog.pg_get_constraintdef(con.oid) AS condef
FROM pg_catalog.pg_constraint AS con
JOIN pg_class AS cl ON cl.relnamespace = con.connamespace AND cl.relfilenode = con.conrelid
WHERE con.conrelid = '<table_relid>'::pg_catalog.oid AND con.contype = 'f';
хороший ресурс для системных таблиц PostgreSQL можно найти здесь. Кроме того, вы можете узнать больше о внутренних запросах pg_dump
делает для того чтобы собрать сброс информация при просмотре это исходный код.
вероятно, самый простой способ увидеть, как pg_dump
собирает все ваши данные будут использовать strace
на нем, вот так:
$ strace -f -e sendto -s8192 -o pg_dump.trace pg_dump -s -n <schema>
$ grep -oP '(SET|SELECT)\s.+(?=\0)' pg_dump.trace
вам все равно придется сортировать болото операторов, но это должно помочь вам собрать инструмент клонирования программно и избежать падения в оболочку для вызова pg_dump
.
я поделюсь решением моей проблемы, которое было таким же с небольшим добавлением. Мне нужно было клонировать схему, создать нового пользователя базы данных и назначить этому пользователю право собственности на все объекты в новой схеме.
в следующем примере Предположим, что ссылочная схема называется ref_schema и целевая схема new_schema. Ссылочная схема и все объекты внутри принадлежат Пользователю с именем ref_user.
1. дамп ссылочной схемы с помощью pg_dump:
pg_dump -n ref_schema -f dump.sql database_name
2. создайте нового пользователя базы данных с именем new_user:
CREATE USER new_user
3. переименуйте схему ref_schema to new_schema:
ALTER SCHEMA ref_schema RENAME TO new_schema
4. измените владельца всех объектов в переименованной схеме на нового пользователя
REASSIGN OWNED BY ref_user TO new_user
5. восстановите исходную ссылочную схему из дампа
psql -f dump.sql database_name
надеюсь, кто-то найдет это полезным.