将MySQL转储导入PostgreSQL数据库

将MySQL转储导入PostgreSQL数据库,mysql,postgresql,Mysql,Postgresql,如何将“xxxx.sql”转储文件从MySQL导入PostgreSQL数据库?您可以先导入,然后再导入。无法将Oracle(二进制)转储文件导入PostgreSQL 如果MySQL转储为纯SQL格式,则需要编辑该文件,以使PostgreSQL的语法正确(例如,删除非标准的反勾引号,删除CREATE TABLE语句的引擎定义,调整数据类型和许多其他内容)不要指望不经编辑就可以工作。可能需要大量的编辑 mysqldump有一个,--compatible=name,其中“name”可以是“oracle

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

您可以先导入,然后再导入。

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


如果MySQL转储为纯SQL格式,则需要编辑该文件,以使PostgreSQL的语法正确(例如,删除非标准的反勾引号,删除CREATE TABLE语句的引擎定义,调整数据类型和许多其他内容)

不要指望不经编辑就可以工作。可能需要大量的编辑

mysqldump有一个,
--compatible=name
,其中“name”可以是“oracle”或“postgresql”,但这并不保证兼容性。我认为像ANSI_引号这样的服务器设置也有一些效果

如果包含创建转储时使用的完整命令以及收到的任何错误消息,而不是简单地说“我什么都不管用”,您将在这里获得更有用的帮助。

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

步骤如下:

  • 从下载Pentaho ETL(社区版)

  • 解压缩并运行Pentaho(spoon.sh/spoon.bat,具体取决于unix/windows)

  • 创建新作业

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

  • 为PostgreSQL源创建数据库连接(如上所述)

  • 运行
    复制表格
    向导(工具->向导->复制表格)

  • 执行任务


  • 下面是一个简单的程序,用于创建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()
    

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

    这是迄今为止最简单的方法,您需要安装它,然后运行一个简单的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,因为在撰写本文时,安装程序有一个bug。(版本3.2.0)

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

    #!/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'.
    
    Total import time          ✓     877567   158.1 MB       1m11.230s
    

    我最近不得不对很多大约7GB的大型.sql文件执行此操作。就连维姆也在编辑这些内容时遇到了麻烦。最好将.sql导入MySql,然后将其导出为csv,然后将其导入Postgres


    但是,MySQL导出为csv的速度非常慢,因为它运行了从您的表中选择的查询。如果您有一个大型数据库/表,我建议您使用其他方法。一种方法是编写一个脚本,逐行读取sql inserts,并使用字符串操作将其重新格式化为“符合Postgres的”insert语句,然后在Postgres中执行这些语句。与大多数数据库迁移一样,实际上并没有现成的解决方案

    在进行迁移时,请记住以下几点:

  • 数据类型不匹配。有些人会,有些人不会。例如,SQL Server位(布尔值)在Oracle中没有等效项
  • 主键序列将在每个数据库中以不同的方式生成
  • 外键将指向您的新序列
  • 索引将不同,可能需要调整
  • 任何存储过程都必须重写
  • 模式。Mysql没有使用它们(至少在我使用它之后没有),Postgresql使用。不要将所有内容都放在公共模式中。这是一种糟糕的做法,但大多数支持Mysql和Postgresql的应用程序(我想到的是Django)都会试图让您使用公共模式
  • 数据迁移。您必须将旧数据库中的所有内容插入到新数据库中。这意味着禁用主键和外键,插入数据,然后启用它们。此外,所有新序列都必须重置为每个表中的最高id。否则,插入的下一条记录将失败,主键冲突
  • 重写代码以使用新数据库。它应该会起作用,但可能不会
  • 不要忘记触发器。我在大多数表上使用创建和更新日期触发器。每个数据库的站点都有点不同 记住这些。最好的方法可能是编写一个转换实用程序。祝你转换愉快

    对于那些2015+年的谷歌用户。
    我在这上面浪费了一整天,我想总结一下

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

    -(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',
    
    因此,您必须根据表手动修复这些类型

    简言之,它是:

    tinyint(2) -> smallint  
    mediumint(7) -> integer
    # etc.
    
    您可以使用
    regex
    和任何很酷的编辑器来完成它

    MacVim
    +
    替换

    :%s!tinyint(\w\+)!smallint!g
    :%s!mediumint(\w\+)!integer!g
    
    MacOSX
    我可以使用将表从MySQL复制到Postgres。
    这不是来自转储,而是在实时数据库之间。

    使用您的xxx.sql文件设置MySQL数据库并利用。非常容易使用,配置短,工作起来很有魅力。它使用设置的主键、外键和标记导入数据库
    sudo apt-get install pgloader
    
    pgloader mysql://user:pass@host/database postgresql://user:pass@host/database
    
    telnet theserverwithmysql 3306
    
    bind-address    = *
    
    createdb databasename
    
    GRANT ALL PRIVILEGES ON DATABASE databasename TO otherusername;
    
    pgloader mysql://theusername:thepassword@theserverwithmysql/databasename postgresql://otherusername@localhost/databasename
    
    Total import time          ✓     877567   158.1 MB       1m11.230s