我正试图将一个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')转换为PostgreSQL的引用要求('O''Connor')。它起作用,直到转储中出现这样的字符串:'以反斜杠结尾的字符串\ '...是的,似乎我们数据库中有一些用户输入具有这种格式,这是完全有效的,但不能通过我的sed命令。我可以添加一个lookbehind到sed命令中,但我感觉自己正在爬进一个兔子洞。是否有办法:
a)告诉mysqldump通过加倍引用单引号来引用单引号 b)告诉psql期望反斜杠被解释为引用转义符号?
我还有另一个与BINARY和bytea差异有关的问题,但我已经通过base64编码/解码阶段解决了这个问题。
编辑|看起来我可以使用“set backslash_quote = on; set standard_conforming_strings = off;”实现(b),但我不确定如何将其注入到管道输出的开头。
complete-insert
和extended-insert
?您可以将所有跳过项与--compact
结合使用。其余部分是必要的,尽管我不想要verbose
。我在MySQL时间戳的默认值上遇到了麻烦,所以我不得不使用sed
。这是我的最终命令:mysqldump --compress --compatible postgresql --no-create-info --compact --default-character-set=utf8 dbname | sed $'s/\'0000-00-00 00:00:00\'/NULL/g' | psql dbname
- Chloe--complete-insert
适用于生产模式与开发模式的列顺序不匹配的情况,无论出于何种原因。你是对的。--extended-insert
是默认开启的。 - Chloe