我正在尝试将数据库从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期望反斜杠被解释为引用转义?
我有BINARY
和bytea
差异的另一个问题,但我已经解决了base64编码/解码阶段。
编辑|看起来我可以用set backslash_quote = on; set standard_conforming_strings = off;
来做(b),虽然我不知道如何将它注入到管道输出的开头。
答案 0 :(得分:3)
答案 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"
是的,“倾斜牙签综合症”,我知道。