18

很久以前在一个很远很远的系统上......

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

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

我想使用 R 编程语言使用 SQL 选择语句分析数据;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

一切都好到这里。接下来,重新启动服务器并使用这些安装说明配置数据库:

  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

用于pgadmin3配置数据库和创建模式。

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

  1. perl Makefile.PL
  2. sudo make install
  3. sudo apt-get install perl-doc(奇怪的是,它没有被调用perldoc
  4. perldoc SQL::Translator::Manual

提取 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

将 MySQL 中的表和列简单地重命名为小写可能是值得的:

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

数据库反击

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

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

这导致:

Query returned successfully with no result in 122 ms.

绝地的回复

在这一点上,我很难过。

  • 我从这里去哪里(步骤是什么)转换climate-my.sql到,climate-pg.sql以便它们可以针对 PostgreSQL 执行?
  • 如何确保正确复制索引(以保持引用完整性;我目前没有限制来缓解过渡)?
  • 如何确保在 PostgreSQL 中添加新行将从插入的最后一行的索引开始枚举(并且不与序列中的现有主键冲突)?
  • 在将数据从 MySQL 转换为 PostgreSQL 插入时,如何确保模式名称通过?

资源

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

谢谢!

4

4 回答 4

4

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

  • 从 MySQL 中提取整个数据库定义并将其调整为 PostgreSQL 语法。
  • 查看数据库定义并对其进行转换,以利用 PostgreSQL 中 MySQL 中不存在的功能。

然后进行转换,并用您最熟悉的任何语言编写一个程序,以完成以下任务:

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

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

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

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

于 2010-05-14T03:53:44.493 回答
2

如果您已经转换了架构,那么迁移数据将是简单的部分:

  • 从 PostgreSQL 转储模式(您说您已将模式转换为 postgres,所以我们现在将转储它,因为我们将删除并重新创建目标数据库,以对其进行清理):

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

  • 仅使用架构的 1 部分重新创建数据库:

    删除数据库 dbname
    创建数据库 dbname
    \i /tmp/dbname-schema-1.sql
    -- 现在我们有了没有数据、触发器、外键等的表。
    
  • 导入数据:

    (
       echo '开始交易';
       mysqldump --skip-quote-names 数据库名 | grep ^插入;
       回声“提交”
    ) | psql 数据库名称
    -- 现在我们有了包含数据的表,但没有触发器、外键等。
    

    MySQL 5.1.3 中添加了一个--skip-quote-names选项,因此如果您有旧版本,则在/tmp/mysqlconfigure --prefix=/tmp/mysql && make install应该做的)中临时安装新的 mysql 并使用/tmp/mysql/bin/mysqldump.

  • 导入架构的其余部分:

    psql 数据库名称
    开始交易
    \i /tmp/dbname-schema-2.sql
    犯罪
    ——我们完成了
    
于 2010-05-14T18:06:37.327 回答
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

这一系列步骤可能不适用于具有多种混合类型的复杂数据库。但是,它适用于integers、varchars 和floats。

索引、主键和序列

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

导入后设置顺序

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

架构前缀

无需使用模式名称为表添加前缀。利用:

SET search_path TO climate;
于 2010-05-14T02:31:15.080 回答
0

看看etlalchemy。它允许您在 4 行 Python 中从MySQL迁移到PostgreSQL,或在其他几个数据库之间迁移。你可以在这里阅读更多关于它的信息。

安装: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()
于 2016-07-22T14:08:32.320 回答