Недавно возникла проблема, по переносу существующих таблиц и данных хранящихся в них из одной реляционной данной в другую. Получилось это сделать при помощи такой замечательной утилиты, как liquibase. Она кроссплатформенная, написанная на языке программирования java.

Итак, имеем mysql, данные из которой нужно перенести на postgresql. Для начало нужно сделать changelog для имеющихся таблиц.

sh liquibase.sh --driver=com.mysql.jdbc.Driver \
      --classpath=<путь до директории, где хранятся jdbc драйвера> \
      --changeLogFile=<путь до директории, где будет храниться файл>/changelogs.xml \
      --url="<адрес к БД, например jdbc:mysql://localhost:3306/test_bd>" \
      --username=<имя пользователя> \
      --password=<пароль> \
      --diffTypes="tables, views, columns, indexes, foreignkeys, primarykeys, uniqueconstraints, data" 
      generateChangeLog

Сгенерируется файл changelogs.xml . Воспользовавшись этим файлом, можно воссоздать структуру на другой БД. Следующая команда это делает — создает таблицы, индексы и пр на postgresql.

sh liquibase.sh \
      --driver=org.postgresql.Driver \
      --classpath=<путь до директории, где хранятся jdbc драйвера>\
      --changeLogFile=<путь до директории, где будет храниться файл>/changelogs.xml \
      --url="jdbc:postgresql://localhost:5432/test_bd" \
      --username=<имя пользователя> \
      --password=<пароль> \
      update

Значение последовательностей при этом не сохраняются, чтобы их выставить необходимо выполнить следующий скрипт.

CREATE OR REPLACE FUNCTION setval_schema(schema_name name, raise_notice boolean = false)
    RETURNS VOID AS
-- Sets all the sequences in the schema "schema_name" to the max(id) of every table
$BODY$
 
DECLARE
    row_data RECORD;
    sql_code TEXT;
 
BEGIN
    IF ((SELECT COUNT(*) FROM pg_namespace WHERE nspname = schema_name) = 0) THEN
        RAISE EXCEPTION 'The schema "%" does not exist', schema_name;
    END IF;
 
    FOR sql_code IN
        SELECT 'SELECT SETVAL(' ||quote_literal(N.nspname || '.' || S.relname)|| ', MAX(' ||quote_ident(C.attname)|| ') ) FROM ' || quote_ident(N.nspname) || '.' || quote_ident(T.relname)|| ';' AS sql_code
            FROM pg_class AS S
            INNER JOIN pg_depend AS D ON S.oid = D.objid
            INNER JOIN pg_class AS T ON D.refobjid = T.oid
            INNER JOIN pg_attribute AS C ON D.refobjid = C.attrelid AND D.refobjsubid = C.attnum
            INNER JOIN pg_namespace N ON N.oid = S.relnamespace
            WHERE S.relkind = 'S' AND N.nspname = schema_name
            ORDER BY S.relname
    LOOP
        IF (raise_notice) THEN
            RAISE NOTICE 'sql_code: %', sql_code;
        END IF;
        EXECUTE sql_code;
    END LOOP;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

SELECT setval_schema('public');
Хотя для данной задачи есть и более простые способы