【问题标题】:Import MySQL dump to PostgreSQL database将 MySQL 转储导入 PostgreSQL 数据库
【发布时间】:2011-07-22 00:04:36
【问题描述】:

如何将“xxxx.sql”转储从 MySQL 导入 PostgreSQL 数据库?

【问题讨论】:

  • 您是如何从 Oracle 创建“xxxx.dump”文件的。你使用 export 或 expdp 或 rdbms.get_ddl 吗?

标签: mysql postgresql


【解决方案1】:

这个问题有点老了,但几天前我正在处理这种情况,发现pgloader.io

这是迄今为止最简单的方法,您需要安装它,然后运行一个简单的 lisp 脚本 (script.lisp),其中包含以下 3 行:

/* content of the script.lisp */
LOAD DATABASE
FROM mysql://dbuser@localhost/dbname
INTO postgresql://dbuser@localhost/dbname;


/*run this in the terminal*/
pgloader script.lisp

之后,您的 postgresql 数据库将拥有您在 MySQL SB 中拥有的所有信息。

附带说明,请确保您编译 pgloader,因为在本文发布时,安装程​​序存在错误。 (版本 3.2.0)

【讨论】:

  • 我感到非常惊喜。工作顺利。在 mac 上: brew install pgloader;命令:pgloader mysql://root@localhost/mydb postgresql:///otherdb
【解决方案2】:

不要指望它在没有编辑的情况下工作。可能需要大量编辑。

mysqldump 有一个compatibility argument--compatible=name,其中“name”可以是“oracle”或“postgresql”,但这并不能保证兼容性。我认为像 ANSI_QUOTES 这样的服务器设置也有一些影响。

如果您包含用于创建转储的完整命令以及收到的任何错误消息,而不是只说“对我没有任何帮助”,您将在此处获得更多有用的帮助。

【讨论】:

  • --compatible=type 不映射数据类型也不注释语法。因此,这仅在省略 DDL 语句时才有效,例如--no-create-info
  • 这并没有回答标题中提出的问题。这显示了如何创建 postgresql 转储,而不是如何将 mysql 转储导入 postgres。
  • 确实如此 - 它解释了如何制作 mysql 转储,它更容易用于在 postgresql 中导入。有关更多信息,请参阅:en.wikibooks.org/wiki/Converting_MySQL_to_PostgreSQL
  • 这个答案解决了我在 2019 年的问题,由于 --no-create-info,我不得不从头开始重新创建表,为此我使用了这两个资源:@ 987654324@ 和这个:convert-in.com/mysql-to-postgres-types-mapping.htm 因为我有这个错误:“错误:类型“双”不存在”
【解决方案3】:

Mac OS X

brew update && brew install pgloader

pgloader mysql://user@host/db_name postgresql://user@host/db_name

【讨论】:

  • 对于--verbose,通过添加双引号和?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory 连接后,我只能得到NOTICE Starting pgloader, log system is ready.
  • 也在 Debian 上工作。
  • 完美解决方案,同样适用于 mac 用户不要忘记,对于 postgres,默认你的 mac 用户名是你的 postgres 用户名
【解决方案4】:

我发现最快(也是最完整)的方法是使用 Kettle。这还将生成所需的表、转换索引和其他所有内容。 mysqldump 兼容性参数不起作用

步骤:

  1. http://kettle.pentaho.org/下载Pentaho ETL(社区版)

  2. 解压并运行 Pentaho(spoon.sh/spoon.bat 取决于 unix/windows)

  3. 创建新作业

  4. 为 MySQL 源创建数据库连接 (工具 -> 向导 -> 创建数据库连接)

  5. 为 PostgreSQL 源创建数据库连接(如上)

  6. 运行Copy Tables 向导(工具 -> 向导 -> 复制表)

  7. 运行作业

【讨论】:

  • 不幸的是,当我运行这项工作时,我遇到了很多错误,这个程序不能很好地运行
  • 它需要一些摆弄才能使其正常工作,这是真的。但多年来我已经多次使用它,这是我发现迁移整个/复杂数据库的最简单方法。
  • 您对 airbyte etl 有什么看法? @GustavoBordin
【解决方案5】:

对于那些 2015 年以上的 Google 员工
我已经浪费了一整天的时间,想总结一下。

我已经尝试了 Alexandru Cotiorasthis 文章中描述的所有解决方案(充满绝望)。在提到的所有解决方案中,只有一个对我有用。

——lanyrd/mysql-postgresql-converter @ github.com (Python)

但仅此一项是行不通的。何时导入新转换的转储文件:

# \i ~/Downloads/mysql-postgresql-converter-master/dump.psql 

PostgreSQL 会告诉你来自MySQL 的混乱类型:

psql:/Users/jibiel/Downloads/mysql-postgresql-converter-master/dump.psql:381: ERROR:  type "mediumint" does not exist
LINE 2:     "group_id" mediumint(8)  NOT NULL DEFAULT '0',

因此,您必须按照this 表手动修复这些类型。

简而言之就是:

tinyint(2) -> smallint  
mediumint(7) -> integer
# etc.

您可以使用regex 和任何很酷的编辑器来完成它。

MacVim + Substitute:

:%s!tinyint(\w\+)!smallint!g
:%s!mediumint(\w\+)!integer!g

【讨论】:

    【解决方案6】:

    【讨论】:

      【解决方案7】:

      您可以使用 pgloader。

      sudo apt-get install pgloader
      

      使用:

      pgloader mysql://user:pass@host/database postgresql://user:pass@host/database
      

      【讨论】:

      【解决方案8】:

      我有这个 bash 脚本来迁移数据,它不会创建表,因为它们是在迁移脚本中创建的,所以我只需要转换数据。我使用表列表不从migrationssessions 表中导入数据。在这里,刚刚测试过:

      #!/bin/sh
      
      MUSER="root"
      MPASS="mysqlpassword"
      MDB="origdb"
      MTABLES="car dog cat"
      PUSER="postgres"
      PDB="destdb"
      
      mysqldump -h 127.0.0.1 -P 6033 -u $MUSER -p$MPASS --default-character-set=utf8 --compatible=postgresql --skip-disable-keys --skip-set-charset --no-create-info --complete-insert --skip-comments --skip-lock-tables $MDB $MTABLES > outputfile.sql
      
      sed -i 's/UNLOCK TABLES;//g' outputfile.sql
      sed -i 's/WRITE;/RESTART IDENTITY CASCADE;/g' outputfile.sql
      sed -i 's/LOCK TABLES/TRUNCATE/g' outputfile.sql
      sed -i "s/'0000\-00\-00 00\:00\:00'/NULL/g" outputfile.sql
      sed -i "1i SET standard_conforming_strings = 'off';\n" outputfile.sql
      sed -i "1i SET backslash_quote = 'on';\n" outputfile.sql
      sed -i "1i update pg_cast set castcontext='a' where casttarget = 'boolean'::regtype;\n" outputfile.sql
      echo "\nupdate pg_cast set castcontext='e' where casttarget = 'boolean'::regtype;\n" >> outputfile.sql
      
      psql -h localhost -d $PDB -U $PUSER -f outputfile.sql
      

      您会收到很多可以放心忽略的警告,如下所示:

      psql:outputfile.sql:82: WARNING:  nonstandard use of escape in a string literal
      LINE 1: ...,(1714,38,2,0,18,131,0.00,0.00,0.00,0.00,NULL,'{\"prospe...
                                                               ^
      HINT:  Use the escape string syntax for escapes, e.g., E'\r\n'.
      

      【讨论】:

      • psql:outputfile.sql:13:错误:关系“端点”不存在。执行 bash 脚本时遇到此错误。
      【解决方案9】:

      pgloader

      获取最新版本的pgloader; Debian Jessie(截至 2019 年 1 月 27 日)提供的版本是 3.1.0 和 won't work,因为 pgloader 会出错

      Can not find file mysql://...
      Can not find file postgres://...
      

      访问 MySQL 源码

      首先,确保您可以在运行 MySQL 的服务器上建立到 mysqld 的连接

      telnet theserverwithmysql 3306
      

      如果失败了

      名称或服务未知

      登录theserverwithmysql,编辑mysqld的配置文件。如果您不知道配置文件在哪里,请使用find / -name mysqld.cnf

      就我而言,我不得不更改mysqld.cnf这一行

      # By default we only accept connections from localhost
      bind-address    = 127.0.0.1
      

      bind-address    = *
      

      请注意,允许从所有地址访问您的 MySQL 数据库可能会带来安全风险,这意味着您可能希望在数据库迁移后更改该值。

      通过重新启动mysqld 使对mysqld.cnf 的更改生效。

      准备 Postgres 目标

      假设您已登录运行 Postgres 的系统,请使用以下命令创建数据库

      createdb databasename
      

      Postgres 数据库的用户必须有足够的权限来创建模式,否则你会遇到

      数据库 databasename 的权限被拒绝

      调用pgloader 时。尽管用户有权根据psql > \du 创建数据库,但我得到了这个错误。

      您可以在psql 中确定这一点:

      GRANT ALL PRIVILEGES ON DATABASE databasename TO otherusername;
      

      同样,如果您将所有这些权限留给用户 otherusername,这可能是权限过度,因此存在安全风险。

      迁移

      最后是命令

      pgloader mysql://theusername:thepassword@theserverwithmysql/databasename postgresql://otherusername@localhost/databasename
      

      在运行 Postgres 的机器上执行的输出应该以这样的一行结尾:

      Total import time          ✓     877567   158.1 MB       1m11.230s
      

      【讨论】:

        【解决方案10】:

        Mac/Win

        下载 Navicat 试用 14 天(我不明白 1300 美元)- 完整的企业包:

        连接数据库mysql和postgres

        菜单 - 工具 - 数据传输

        在第一个屏幕上连接两个数据库。虽然仍在此屏幕上,但有一个常规/选项 - 在右侧检查的选项下检查 - 出错时继续 * 请注意,您可能想取消选中左侧的索引和键.. 您可以在 postgres 中轻松地重新分配它们。

        至少将您的数据从 MySQL 导入 Postgres!

        希望这会有所帮助!

        【讨论】:

        • 这是在 Mac M1(2021 年)上唯一对我有用的东西。 pgloader 在独立和 docker 变体中都不起作用。 Navicat Premium 花了很多时间来加载,但随后按描述工作。唯一的缺点它仍然无法导出外键和索引(产生错误,除非按照说明取消勾选复选框)
        【解决方案11】:

        无法将 Oracle(二进制)转储导入 PostgreSQL。

        如果 MySQL 转储是纯 SQL 格式,您将需要编辑文件以使语法对 PostgreSQL 正确(例如删除非标准反引号,删除 CREATE TABLE 语句的引擎定义调整数据类型还有很多其他的东西)

        【讨论】:

          【解决方案12】:

          这是一个简单的程序,用于创建 mysql 数据库(亲爱的)中的所有表并将其加载到 postgresql。来自 mysql 的类型转换是粗粒度的,但很容易细化。您必须手动重新创建索引:

          import MySQLdb
          from magic import Connect #Private mysql connect information
          import psycopg2
          
          dbx=Connect()
          DB=psycopg2.connect("dbname='honey'")
          DC=DB.cursor()
          
          mysql='''show tables from honey'''
          dbx.execute(mysql); ts=dbx.fetchall(); tables=[]
          for table in ts: tables.append(table[0])
          for table in tables:
              mysql='''describe honey.%s'''%(table)
              dbx.execute(mysql); rows=dbx.fetchall()
              psql='drop table %s'%(table)
              DC.execute(psql); DB.commit()
          
              psql='create table %s ('%(table)
              for row in rows:
                  name=row[0]; type=row[1]
                  if 'int' in type: type='int8'
                  if 'blob' in type: type='bytea'
                  if 'datetime' in type: type='timestamptz'
                  psql+='%s %s,'%(name,type)
              psql=psql.strip(',')+')'
              print psql
              try: DC.execute(psql); DB.commit()
              except: pass
          
              msql='''select * from honey.%s'''%(table)
              dbx.execute(msql); rows=dbx.fetchall()
              n=len(rows); print n; t=n
              if n==0: continue #skip if no data
          
              cols=len(rows[0])
              for row in rows:
                  ps=', '.join(['%s']*cols)
                  psql='''insert into %s values(%s)'''%(table, ps)
                  DC.execute(psql,(row))
                  n=n-1
                  if n%1000==1: DB.commit(); print n,t,t-n
              DB.commit()
          

          【讨论】:

            【解决方案13】:

            与大多数数据库迁移一样,实际上并没有一刀切的解决方案。

            在进行迁移时要牢记以下几点:

            1. 数据类型不匹配。有些会,有些不会。例如,SQL Server 位(布尔值)在 Oracle 中没有等效项。
            2. 主键序列将在每个数据库中生成不同。
            3. 外键将指向您的新序列。
            4. 索引会有所不同,可能需要调整。
            5. 任何存储过程都必须重写
            6. 架构。 Mysql 不使用它们(至少自从我使用它以来没有),Postgresql 使用它们。不要将所有内容都放在公共架构中。这是一个不好的做法,但大多数支持 Mysql 和 Postgresql 的应用程序(想到 Django)都会尝试让您使用公共模式。
            7. 数据迁移。您将不得不将旧数据库中的所有内容插入到新数据库中。这意味着禁用主键和外键,插入数据,然后启用它们。此外,您的所有新序列都必须重置为每个表中的最高 id。如果不是,则插入的下一条记录将因主键冲突而失败。
            8. 重写代码以使用新数据库。它应该工作,但可能不会。
            9. 不要忘记触发器。我在我的大多数表上使用创建和更新日期触发器。每个数据库的站点都略有不同。

            记住这些。最好的方法可能是编写一个转换实用程序。有一个快乐的转换!

            【讨论】:

              【解决方案14】:

              我最近不得不对许多大小约为 7 GB 的大型 .sql 文件执行此操作。即使是 VIM 也很难编辑这些。最好的办法是将 .sql 导入 MySql,然后将其导出为 csv,然后可以将其导入 Postgres。

              但是,MySQL 导出为 csv 非常慢,因为它运行 select * from yourtable 查询。如果您有一个大型数据库/表,我建议您使用其他方法。一种方法是编写一个脚本,逐行读取 sql 插入并使用字符串操作将其重新格式化为“符合 Postgres”的插入语句,然后在 Postgres 中执行这些语句

              【讨论】:

                【解决方案15】:

                我可以使用DBCopy Plugin for SQuirreL SQL Client 将表从 MySQL 复制到 Postgres。 这不是来自转储,而是来自实时数据库。

                【讨论】:

                  【解决方案16】:

                  使用您的 xxx.sql 文件设置 MySQL 数据库并使用FromMysqlToPostrgreSQL。非常易于使用,配置简短,就像一个魅力。它使用表上设置的主键、外键和索引导入您的数据库。如果您在配置文件中设置适当的标志,您甚至可以单独导入数据。

                  Anatoly Khaytovich 的 FromMySqlToPostgreSql 迁移工具,提供表数据、索引、PK、FK 的准确迁移...广泛使用 PostgreSQL COPY 协议。

                  也见这里:PG Wiki Page

                  【讨论】:

                    【解决方案17】:

                    如果您使用 phpmyadmin,您可以将数据导出为 CSV,然后在 postgres 中导入会更容易。

                    【讨论】:

                      【解决方案18】:
                      1. 获取 mysql 数据库的转储文件。
                      2. 使用此工具将本地 mysql 数据库转换为本地 postgresql 数据库。
                      • 在新文件夹或根目录中克隆:

                        1. git clone https://github.com/AnatolyUss/nmig.git
                        2. cd nmig
                        3. git checkout v5.5.0
                        4. nano config/config.json结帐后打开此文件。
                        5. 添加源数据库和目标数据库以及用户名、密码
                        "source": {
                        "host": "localhost",
                        "port": 3306,
                        "database": "test_db",
                        "charset": "utf8mb4",
                        "supportBigNumbers": true,
                        "user": "root",
                        "password": "0123456789"
                        }
                        "target": {
                          "host"     : "localhost",
                          "port"     : 5432,
                          "database" : "test_db",
                          "charset"  : "UTF8",
                          "user"     : "postgres",
                          "password" : "0123456789"
                        }
                        
                        1. 修改config/config.json文件后运行:
                          1. npm install
                          2. npm run build
                          3. npm start
                        2. 执行完所有这些命令后,您会注意到 mysql 数据库已转移到 postgresql 数据库。

                      【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2016-10-16
                      • 2016-08-21
                      • 2015-05-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多