将MySQL转储导入PostgreSQL数据库

时间:2011-03-24 09:57:32

标签: mysql postgresql

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

17 个答案:

答案 0 :(得分:36)

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

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

/* 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)

答案 1 :(得分:22)

不要指望在没有编辑的情况下工作。也许很多编辑。

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

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

答案 2 :(得分:12)

Mac OS X

brew update && brew install pgloader

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

答案 3 :(得分:10)

我找到的最快(也是最完整)的方法是使用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. 运行作业

答案 4 :(得分:10)

对于2015年<+ em>的那些Google员工 我整天都浪费在这上面,并希望总结一下。

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

- 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

答案 5 :(得分:7)

答案 6 :(得分:5)

我有这个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'.

答案 7 :(得分:5)

您可以使用pgloader。

sudo apt-get install pgloader

使用:

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

答案 8 :(得分:4)

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

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

答案 9 :(得分:2)

这是一个简单的程序,用于创建和加载mysql数据库(honey)中的所有表到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()

答案 10 :(得分:1)

与大多数数据库迁移一样,并不是真正的切割和干燥解决方案。

这些是在进行迁移时要记住的一些想法:

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

答案 11 :(得分:1)

使用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在运行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.cnf使对mysqld的更改生效。

准备Postgres目标

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

createdb databasename

Postgres数据库的用户必须具有足够的特权才能创建模式,否则您将遇到

  

数据库数据库名的权限被拒绝

在致电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

答案 12 :(得分:1)

Mac / Win

下载Navicat试用版14天(我不了解1300美元)-完整的企业版软件包:

同时连接mysql和postgres数据库

菜单-工具-数据传输

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

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

希望这会有所帮助!

答案 13 :(得分:0)

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

  

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

另见:PG Wiki Page

答案 14 :(得分:0)

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

答案 15 :(得分:0)

我最近必须对大量大小为7 GB的大型.sql文件执行此操作。即便是VIM也难以编辑。最好的办法是将.sql导入MySql,然后将其导出为csv,然后将其导入Postgres。

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

答案 16 :(得分:0)

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