Son 8 saatimi 'mysqldump --compatible = postgresql' çıktısını PostgreSQL 8.4.9'a aktarmaya çalışarak geçirdim ve burada ve başka bir yerde bu özel sorun hakkında zaten en az 20 farklı konu okudum, ancak gerçek kullanılabilir cevap çalışır.
MySQL 5.1.52 verisi dökümü:
mysqldump -u root -p --compatible=postgresql --no-create-info --no-create-db --default-character-set=utf8 --skip-lock-tables rt3 > foo
Hedef olarak PostgreSQL 8.4.9 sunucusu
Verileri 'psql -U rt_user -f foo' ile yüklemek bildiriyor (bunların çoğu, bir örnek):
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".
Aşağıdakilere göre, girdi dosyasında NULL (0x00) karakter yok.
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
Benzer şekilde, Perl ile yapılan bir başka kontrolde NULL gösterilmez:
database-dumps:rcf-temp1# perl -ne '/\000/ and print;' foo
database-dumps:rcf-temp1#
Hata "HINT" olarak, 'client_encoding' 'UTF8' ayarlamak için mümkün olan her yolu denedim ve başarılı ama sorunumu çözmek için hiçbir etkisi yoktur.
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#
Mükemmel, yine de:
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".
...
"Hoyle göre" doğru cevabı engellemek, duymak harika olurdu ve bu nadiren referans verilen veriler için ASCII olmayan karakterleri korumayı gerçekten umursamadığımı bilmek, ne önerileriniz var?
Güncelleme: İçe aktarım sırasında aynı döküm dosyasının yalnızca ASCII sürümüyle aynı hatayı alıyorum. Gerçekten akıl almaz:
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
Söz konusu tablolardan biri şu şekilde tanımlanmıştır:
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)
DB şemasının herhangi bir parçası için türü değiştirme özgürlüğüm yok. Aksi takdirde, yazılımın gelecekteki yükseltmelerini bozabilir .
Muhtemel sorun sütunu, 'metin' türündeki 'içerik' dir (belki de diğer tablolardaki diğerleri). Önceki araştırmalardan bildiğim gibi, PostgreSQL 'metin' değerlerinde NULL değerine izin vermeyecektir. Bununla birlikte, lütfen hem sed hem de Perl'in NULL karakter göstermediği yerlere bakın ve daha sonra aşağıya tüm döküm dosyasından tüm ASCII olmayan karakterleri soyduğum ama yine de barfs.
head -29 foo | tail -1 | cat -v
işe yarayabilir.