数据从mysql迁移到postgresql

发布于:2025-08-08 ⋅ 阅读:(16) ⋅ 点赞:(0)

参考文章:

项目从 MySQL 切换 PostgreSQL,踩了太多的坑!

需要安装一个工具pgloader

Installing pgloader — pgloader 3.6.9 documentation

windows下没有可用的exec打包,只能通过docker使用

docker pull ghcr.io/dimitri/pgloader:latest
docker run --rm -it ghcr.io/dimitri/pgloader:latest pgloader --version

迁移命令举例

docker run --rm -it --memory 4g --memory-swap 4g ghcr.io/dimitri/pgloader:latest pgloader --encoding UTF8 --set "client_encoding = 'UTF8'" --cast "type int to integer drop typemod" --cast "type bigint to bigint drop typemod" --cast "type timestamp to timestamp" --cast "type datetime to timestamp" mysql://用户名:密码@192.168.0.102:3357/库名 postgresql://用户名:密码@192.168.0.102:5432/库名

数据库不能太大,不然会报错oom,目前还没找到解决办法

另外:

pgloader迁移,默认会把日期timestamp、datetime等变成postgresql下带时区的timestamptz格式,上面的迁移指令里--cast "type timestamp to timestamp"的指令,就是要求把时间转成不带时区的timestamp格式,但是有个bug:

`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
这样的带有ON UPDATE CURRENT_TIMESTAMP的字段,仍然会转成timestamptz格式

解决办法:

-- 在postgresql命令行里执行,把所有update_time转成不带时区格式timestamp
DO $$
DECLARE
    r RECORD;
BEGIN
    FOR r IN
        SELECT table_schema, table_name
        FROM information_schema.columns
        WHERE column_name = 'update_time'
          AND data_type = 'timestamp with time zone'
    LOOP
        EXECUTE format('ALTER TABLE %I.%I ALTER COLUMN update_time TYPE TIMESTAMP', r.table_schema, r.table_name);
    END LOOP;
END $$;

批量设置时间默认值脚本:

批量修改模式名下的所有字段类型为timestamp的并且字段名为 create_time 或者 update_time的字段的默认值为 CURRENT_TIMESTAMP

-- 注意 || 号拼接的后面的字符串前面要有一个空格
DO $$
DECLARE
    rec RECORD;
BEGIN
    FOR rec INSELECT table_name, column_name,data_type
               FROM information_schema.columns
               where table_schema = '要处理的模式名'
                 AND data_type = 'timestamp without time zone'
                 -- 修改的字段名
          and column_name in ('create_time','update_time')
    LOOP
         EXECUTE'ALTER TABLE ' || rec.table_name || ' ALTER COLUMN ' || rec.column_name || ' SET DEFAULT CURRENT_TIMESTAMP;';
    ENDLOOP;
END $$;

如果不想使用pgloader或者觉得pgloader的转换有问题(比如自增字段的转换),也可以使用navicat复制数据库转换,然后自行修改自增字段数据类型。

注意,navicat15对postgresql的支持尚不完善,我升级用navicat17

postgresql数据备份和恢复

#备份数据
pg_dump -h localhost -p 5432 -U postgres -W -d 数据库名 -n public -f backup.sql
Password:

#恢复数据
psql -h localhost -p 5432 -U postgres -W -d 数据库名 -n public -f backup.sql
Password:

授予超级用户权限

将目标用户设置为超级用户。超级用户在 PostgreSQL 中拥有所有权限,可以执行任何操作。

ALTER USER your_username WITH SUPERUSER;


网站公告

今日签到

点亮在社区的每一天
去签到