获取mysqldump来转储适合psql输入的数据(转义单引号)

时间:2012-09-02 13:33:16

标签: mysql postgresql mysqldump psql

我正在尝试将数据库从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命令之外的所有内容都是可管理的。我正在做sed尝试转换MySQL的方法来引用字符串中的单引号('O\'Connor')o PostgreSQL的引用要求('O''Connor')。它有效,直到在转储中有这样的字符串:'String ending with a backslash \\' ...是的,似乎我们的数据库中有一些用户输入具有这种格式,这是完全有效的,但是没有通过我的sed命令。我可以在sed命令中添加一个lookbehind,但我觉得我正爬进一个兔子洞。有没有办法:

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

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

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

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

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

psql的这些设置结合以下mysqldump命令将成功将仅数据从mysql 5.1迁移到带有UTF-8文本的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>

答案 2 :(得分:1)

试试这个:

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

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