Passei as últimas 8 horas tentando importar a saída do 'mysqldump --compatible = postgresql' para o PostgreSQL 8.4.9 e li pelo menos 20 threads diferentes aqui e eles já em algum lugar sobre esse problema específico, mas não encontrei resposta útil real que funciona.
Dados do MySQL 5.1.52 despejados:
mysqldump -u root -p --compatible=postgresql --no-create-info --no-create-db --default-character-set=utf8 --skip-lock-tables rt3 > foo
Servidor PostgreSQL 8.4.9 como destino
O carregamento dos dados com 'psql -U rt_user -f foo' está sendo relatado (muitos deles, aqui está um exemplo):
psql:foo:29: ERROR: invalid byte sequence for encoding "UTF8": 0x00
HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
De acordo com o seguinte, não há caracteres NULL (0x00) no arquivo de entrada.
database-dumps:rcf-temp1# sed 's/\x0/ /g' < foo > nonulls
database-dumps:rcf-temp1# sum foo nonulls
04730 2545610 foo
04730 2545610 nonulls
database-dumps:rcf-temp1# rm nonulls
Da mesma forma, outra verificação com Perl não mostra NULLs:
database-dumps:rcf-temp1# perl -ne '/\000/ and print;' foo
database-dumps:rcf-temp1#
Como o "HINT" no erro menciona, tentei de todas as formas possíveis definir 'client_encoding' como 'UTF8', e obtive sucesso, mas isso não tem efeito na solução do meu problema.
database-dumps:rcf-temp1# psql -U rt_user --variable=client_encoding=utf-8 -c "SHOW client_encoding;" rt3
client_encoding
-----------------
UTF8
(1 row)
database-dumps:rcf-temp1#
Perfeito, ainda:
database-dumps:rcf-temp1# psql -U rt_user -f foo --variable=client_encoding=utf-8 rt3
...
psql:foo:29: ERROR: invalid byte sequence for encoding "UTF8": 0x00
HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
...
Exceto a resposta correta "De acordo com Hoyle", o que seria fantástico de ouvir, e sabendo que realmente não me importo em preservar caracteres não ASCII para esses dados raramente referenciados, que sugestões você tem?
Atualização: Eu recebo o mesmo erro com uma versão somente ASCII do mesmo arquivo de despejo no momento da importação. Verdadeiramente incompreensível:
database-dumps:rcf-temp1# # convert any non-ASCII character to a space
database-dumps:rcf-temp1# perl -i.bk -pe 's/[^[:ascii:]]/ /g;' mysql5-dump.sql
database-dumps:rcf-temp1# sum mysql5-dump.sql mysql5-dump.sql.bk
41053 2545611 mysql5-dump.sql
50145 2545611 mysql5-dump.sql.bk
database-dumps:rcf-temp1# cmp mysql5-dump.sql mysql5-dump.sql.bk
mysql5-dump.sql mysql5-dump.sql.bk differ: byte 1304850, line 30
database-dumps:rcf-temp1# # GOOD!
database-dumps:rcf-temp1# psql -U postgres -f mysql5-dump.sql --variable=client_encoding=utf-8 rt3
...
INSERT 0 416
psql:mysql5-dump.sql:30: ERROR: invalid byte sequence for encoding "UTF8": 0x00
HINT: This error can also happen if the byte sequence does not match the encod.
INSERT 0 455
INSERT 0 424
INSERT 0 483
INSERT 0 447
INSERT 0 503
psql:mysql5-dump.sql:36: ERROR: invalid byte sequence for encoding "UTF8": 0x00
HINT: This error can also happen if the byte sequence does not match the encod.
INSERT 0 502
INSERT 0 507
INSERT 0 318
INSERT 0 284
psql:mysql5-dump.sql:41: ERROR: invalid byte sequence for encoding "UTF8": 0x00
HINT: This error can also happen if the byte sequence does not match the encod.
INSERT 0 382
INSERT 0 419
INSERT 0 247
psql:mysql5-dump.sql:45: ERROR: invalid byte sequence for encoding "UTF8": 0x00
HINT: This error can also happen if the byte sequence does not match the encod.
INSERT 0 267
INSERT 0 348
^C
Uma das tabelas em questão é definida como:
Table "public.attachments"
Column | Type | Modifie
-----------------+-----------------------------+--------------------------------
id | integer | not null default nextval('atta)
transactionid | integer | not null
parent | integer | not null default 0
messageid | character varying(160) |
subject | character varying(255) |
filename | character varying(255) |
contenttype | character varying(80) |
contentencoding | character varying(80) |
content | text |
headers | text |
creator | integer | not null default 0
created | timestamp without time zone |
Indexes:
"attachments_pkey" PRIMARY KEY, btree (id)
"attachments1" btree (parent)
"attachments2" btree (transactionid)
"attachments3" btree (parent, transactionid)
Não tenho a liberdade de alterar o tipo de qualquer parte do esquema do banco de dados. Isso provavelmente quebraria futuras atualizações do software etc.
A coluna do problema provável é 'conteúdo' do tipo 'texto' (talvez outros também em outras tabelas). Como eu já sei em pesquisas anteriores, o PostgreSQL não permitirá NULL em valores de 'texto'. No entanto, veja acima, onde sed e Perl não mostram caracteres NULL, e mais abaixo, onde retiro todos os caracteres não ASCII de todo o arquivo de despejo, mas ele ainda vomita.
head -29 foo | tail -1 | cat -v
pode ser útil.