在Linux(Kubuntu)上从MySQL迁移到PostgreSQL

时间:2010-05-13 23:48:45

标签: mysql postgresql database-migration

很久以前,很远很远的系统......

尝试将数据库从MySQL迁移到PostgreSQL。我阅读的所有文档都非常详细地介绍了如何迁移结构。我发现很少有关于迁移数据的文档。该模式有13个表(已成功迁移)和9 GB数据。

MySQL版本:5.1.x
PostgreSQL版本:8.4.x

我想使用R编程语言使用SQL select语句分析数据; PostgreSQL有PL / R,但MySQL没有任何东西(据我所知)。

新希望

创建数据库位置(/var空间不足;也不喜欢在任何地方都有PostgreSQL版本号 - 升级会破坏脚本!):

  1. sudo mkdir -p /home/postgres/main
  2. sudo cp -Rp /var/lib/postgresql/8.4/main /home/postgres
  3. sudo chown -R postgres.postgres /home/postgres
  4. sudo chmod -R 700 /home/postgres
  5. sudo usermod -d /home/postgres/ postgres
  6. 一切都好到这里。接下来,重新启动服务器并使用这些installation instructions

    配置数据库
    1. sudo apt-get install postgresql pgadmin3
    2. sudo /etc/init.d/postgresql-8.4 stop
    3. sudo vi /etc/postgresql/8.4/main/postgresql.conf
    4. data_directory更改为/home/postgres/main
    5. sudo /etc/init.d/postgresql-8.4 start
    6. sudo -u postgres psql postgres
    7. \password postgres
    8. sudo -u postgres createdb climate
    9. pgadmin3
    10. 使用pgadmin3配置数据库并创建架构。

      剧集在一个称为bash的远程shell中继续,两个数据库都在运行,并且安装了一组带有相当不寻常徽标的工具:SQL Fairy

      1. perl Makefile.PL
      2. sudo make install
      3. sudo apt-get install perl-doc(奇怪的是,它不叫perldoc
      4. perldoc SQL::Translator::Manual
      5. 提取PostgreSQL友好的DDL和所有MySQL数据:

        1. sqlt -f DBI --dsn dbi:mysql:climate --db-user user --db-password password -t PostgreSQL > climate-pg-ddl.sql
        2. 编辑climate-pg-ddl.sql并将标识符转换为小写,然后插入架构引用(使用VIM):
          • :%s/"\([A-Z_]*\)"/\L\1/g
          • :%s/ TABLE / TABLE climate./g
          • :%s/ on / on climate./g
        3. mysqldump --skip-add-locks --complete-insert --no-create-db --no-create-info --quick --result-file="climate-my.sql" --databases climate --skip-comments -u root -p
        4. 将MySQL中的表和列重命名为小写可能是值得的:

          1. select concat( 'RENAME TABLE climate.', TABLE_NAME, ' to climate.', lower(TABLE_NAME), ';' ) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='climate';
          2. 执行上一步中的命令。
          3. 可能有一种方法可以对列进行相同的操作;我手动更改了它们,因为它比确定如何编写查询更快。
          4. 数据库反击

            在PostgreSQL中重新创建结构,如下所示:

            1. pgadmin3(切换到它)
            2. 单击执行任意SQL查询图标
            3. 打开climate-pg-ddl.sql
            4. 搜索TABLE "替换为TABLE climate."(插入架构名称climate
            5. 搜索on "替换为on climate."(插入架构名称climate
            6. F5执行
            7. 这导致:

              Query returned successfully with no result in 122 ms.
              

              Jedi的回复

              此时我很难过。

              • 我从哪里开始(步骤)将climate-my.sql转换为climate-pg.sql,以便可以针对PostgreSQL执行这些步骤?
              • 如何确保正确复制索引(以保持参照完整性;我目前没有约束来简化转换)?
              • 如何确保在PostgreSQL中添加新行将从插入的最后一行的索引开始枚举(并且不会与序列中的现有主键冲突)?
              • 在将数据从MySQL转换为PostgreSQL插件时,如何确保模式名称出现?

              资源

              需要相当多的信息才能做到这一点:

              谢谢!

4 个答案:

答案 0 :(得分:4)

我通常为此类迁移做的事情有两方面:

  • 从MySQL中提取整个数据库定义并使其适应PostgreSQL语法。
  • 浏览数据库定义并对其进行转换,以利用PostgreSQL中MySQL中不存在的功能。

然后进行转换,并用您最熟悉的任何语言编写程序,以实现以下目标:

  • 从MySQL数据库中读取数据。
  • 对要存储在PostgreSQL数据库中的数据执行必要的转换。
  • 将现已转换的数据保存在PostgreSQL数据库中。

重新设计PostgreSQL的表格以利用其功能。

如果您只是使用sed脚本将SQL转储从一种格式转换为下一种格式,那么您所做的就是将一个MySQL数据库放在PostgreSQL服务器中。您可以这样做,这样做仍然会带来一些好处,但如果您要迁移,请完全迁移。

这将花费更多的前期时间,但我还没有遇到过不值得的情况。

答案 1 :(得分:2)

将mysqldump文件转换为PostgreSQL友好格式

按如下方式转换数据(不要使用mysql2pgsql.perl):

  1. 转义引号。

    sed "s/\\\'/\'\'/g" climate-my.sql | sed "s/\\\r/\r/g" | sed "s/\\\n/\n/g" > escaped-my.sql

  2. 用搜索路径替换USE "climate";并评论评论:

    sed "s/USE \"climate\";/SET search_path TO climate;/g" escaped-my.sql | sed "s/^\/\*/--/" > climate-pg.sql

  3. 连接数据库。

    sudo su - postgres
    psql climate

  4. 设置编码(mysqldump忽略其编码参数),然后执行脚本。

    \encoding iso-8859-1
    \i climate-pg.sql

  5. 这一系列步骤可能不适用于具有许多混合类型的复杂数据库。但是,它适用于integer s,varcharfloat s。

    索引,主键和序列

    由于mysqldump在生成INSERT语句时包含主键,因此它们将胜过表的自动序列。所有表格的序列在检查时保持为1。

    导入后设置序列

    使用ALTER SEQUENCE命令将它们设置为所需的任何值。

    架构前缀

    不需要使用模式名称为表添加前缀。使用:

    SET search_path TO climate;
    

答案 2 :(得分:2)

如果您已经转换了架构,那么迁移数据将是一件容易的事情:

  • 从PostgreSQL转储模式(你说你已经将模式转换为postgres,所以我们暂时将其转储,因为我们将删除并重新创建目标数据库,以便清除它):

    pg_dump dbname > /tmp/dbname-schema.sql
    
  • 将模式拆分为2个部分 - /tmp/dbname-schema-1.sql包含create table语句,/tmp/dbname-schema-2.sql - 其余部分。 PostgreSQL需要在导入外键,触发器等之前导入数据,但是在导入表定义之后。

  • 仅使用一部分模式重新创建数据库:

    drop database dbname
    create database dbname
    \i /tmp/dbname-schema-1.sql
    -- now we have tables without data, triggers, foreign keys etc.
    
  • 导入数据:

    (
       echo 'start transaction';
       mysqldump --skip-quote-names dbname | grep ^INSERT;
       echo 'commit'
    ) | psql dbname
    -- now we have tables with data, but without triggers, foreign keys etc.
    

    MySQL 5.1.3中添加了--skip-quote-names选项,因此如果您的版本较旧,请在/tmp/mysqlconfigure --prefix=/tmp/mysql && make install应该执行)中临时安装较新的mysql并使用{{1 }}

  • 导入架构的其余部分:

    psql dbname
    start transaction
    \i /tmp/dbname-schema-2.sql
    commit
    -- we're done
    

答案 3 :(得分:0)

结帐etlalchemy。它允许您从4行Python中的 MySQL 迁移到 PostgreSQL ,或者在其他几个数据库之间迁移。您可以阅读更多相关信息here

安装:pip install etlalchemy

运行:

from etlalchemy import ETLAlchemySource, ETLAlchemyTarget
# Migrate from MySQL to PostgreSQL
src = ETLAlchemySource("mysql://user:passwd@hostname/dbname")
tgt = ETLAlchemyTarget("postgresql://user:passwd@hostname/dbname",
                          drop_database=True)
tgt.addSource(src)
tgt.migrate()