4

我正在尝试将数据库从 MySQL 移植到 PostgreSQL。我已经在 Postgres 中重建了模式,所以我需要做的就是获取数据,而无需重新创建表。

我可以使用迭代所有记录并一次插入一个的代码来做到这一点,但是我尝试了这一点,而且我们的数据库大小变慢了,所以我尝试使用 mysqldump 和一个管道来代替 psql(每次一次表,一旦我开始工作,我可能会并行化)。

我必须跳过各种障碍才能走到这一步,打开和关闭各种标志以获得模糊不清的转储。同样,这只会转储 INSERT INTO,因为我已经准备好空模式以将数据放入:

      /usr/bin/env \
      PGPASSWORD=mypassword \
      mysqldump \
      -h mysql-server \
      -u mysql-username \
      --password=mysql-password \
      mysql-database-name \
      table-name \
      --compatible=postgresql \
      --compact \
      -e -c -t \
      --default-character-set=utf8 \
      | sed "s/\\\\\\'/\\'\\'/g" \
      | psql \
      -h postgresql-server \
      --username=postgresql-username \
      postgresql-database-name

sed除了那个丑陋的命令之外的一切都是可以管理的。我这样做是为了尝试将 MySQL 的方法转换为在字符串 ( ) o PostgreSQL 的引用要求 ( )sed中引用单引号。它可以工作,直到转储中出现这样的字符串:...是的,我们的数据库中似乎有一些用户输入具有这种格式,这是完全有效的,但没有通过我的命令。我可以在命令中添加一个lookbehind,但我觉得我正在爬进一个兔子洞。有没有办法:'O\'Connor''O''Connor''String ending with a backslash \\'sedsed

a) 告诉 mysqldump 通过将单引号加倍来引用单引号 b) 告诉 psql 期望反斜杠被解释为引用转义?

我有另一个问题BINARYbytea差异,但我已经通过 base64 编码/解码阶段解决了这个问题。

编辑 | 看起来我可以用 (b) 做set backslash_quote = on; set standard_conforming_strings = off;,但我不确定如何将它注入管道输出的开头。

4

3 回答 3

3

使用 mysqldump 的选项将表转储到 TSV --tab,然后使用 psql 的COPY方法导入。

于 2012-09-02T14:04:16.907 回答
3

文件 psqlrc 和 ~/.psqlrc 可能包含客户端启动时要执行的 SQL 命令。您可以将这三行或您想要的任何其他设置放在该文件中。

SET standard_conforming_strings = 'off';
SET backslash_quote = 'on';
SET escape_string_warning = 'off';

psql 的这些设置与以下 mysqldump 命令相结合,将仅使用 UTF-8 文本(在我的情况下为中文)成功地将数据从 mysql 5.1 迁移到 postgresql 9.1。如果创建中间文件太大或太耗时,则此方法可能是迁移大型数据库的唯一合理方法。这需要您手动迁移模式,因为这两个数据库的数据类型大不相同。计划输入一些 DDL 以使其正确。

mysqldump \
--host=<hostname> \
--user=<username> \
--password=<password> \
--default-character-set=utf8 \
--compatible=postgresql \
--complete-insert \
--extended-insert \
--no-create-info \
--skip-quote-names \
--skip-comments \
--skip-lock-tables \
--skip-add-locks \
--verbose \
<database> <table> | psql -n -d <database>
于 2013-05-24T10:09:31.430 回答
1

试试这个:

sed -e "s/\\\\'/\\\\\\'/g" -e "s/\([^\\]\)\\\\'/\1\\'\\'/g"

是的,“倾斜牙签综合症”,我知道。

于 2012-09-02T14:02:12.473 回答