Kaynak veritabanı UTF8'de kodlandığında, bir geri yüklemede UTF8 geçersiz bayt dizisi kopyalama hatalarını nasıl çözebilirim?


17

Başka bir sunucuya PostgreSQL 8.2.x veritabanını taşımak için görev verildi. Bunu yapmak için pgAdmin 1.12.2 (bu arada Ubuntu 11.04'te) kullanıyorum ve özel / sıkıştırma formatı (.backup) ve UTF8 kodlamasını kullanarak Yedekleme ve Geri Yükleme'yi kullanıyorum.

Orijinal veritabanı şu şekilde UTF8'de bulunur:

-- Database: favela

-- DROP DATABASE favela;

CREATE DATABASE favela
  WITH OWNER = favela
       ENCODING = 'UTF8'
       TABLESPACE = favela
       CONNECTION LIMIT = -1;

Bu veritabanını tam olarak hedef sunucuda bu şekilde oluşturuyorum. Ancak Geri Yükleme seçeneğini kullanarak veritabanını .backup dosyasından geri yüklediğimde bana bu hatalardan bazılarını verir:

pg_restore: restoring data for table "arena"
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 2173; 0 35500 TABLE DATA arena favela
pg_restore: [archiver (db)] COPY failed: ERROR:  invalid byte sequence for encoding "UTF8": 0xe3a709
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".
CONTEXT:  COPY arena, line 62

Aslında hangi kaydın bu hatayı tetiklediğini kontrol ettiğimde, bazı vartext alanlarının ç gibi aksan karakterleri var (örneğin Portekizce, "caça") ve kayıtlardaki metinden manuel olarak kaldırdığımda hata bir sonraki kayda geçiyor kopyada bir hata olduğunda bu tabloya veri eklemeyi durdurur. Bunu başarmak için bunları tek tek manuel olarak değiştirmek istemiyorum.

Ama biraz garip çünkü UTF8 ile bu tür problemler olmamalı, değil mi?

İlk etapta oraya nasıl geldiklerini bilmiyorum. Ben sadece veritabanını geçiriyorum ve bir şekilde veritabanı LATIN1 gibi olduğunu ve daha sonra yanlış UTF8 olarak değiştirildiğini varsayalım.

Bir tablonun / veritabanının geçersiz UTF8 dizileri olup olmadığını kontrol etmenin herhangi bir yolu var mı? Ya da bu karakterleri UFT8'e zorlamak / yeniden dönüştürmek için herhangi bir yol, böylece geri yüklemeyi yürütürken herhangi bir sorunla karşılaşmam?

Şimdiden teşekkürler.

Yanıtlar:


8

İnternette dolaşırken bunun oldukça yaygın bir sorun olduğunu gördüm. Ortak çözüm, düz metin biçimi dökümünü kullanmak ve kodlamayı düzeltmek için iconv aracılığıyla beslemektir.

İşte bunun hakkında daha fazla bilgi.


geçersiz sembolleri atarak UTF-32'ye dönüştürmek için iconv kullanın ve ardından UTF-8'e geri dönün, UTF-8'den UTF-8'e dönüştürme tüm kötü kod noktalarını yakalamaz. (ör. yetim vekiller)
Jasen

7

"Oraya nasıl geldiklerini bilmiyorum"

Açıklandığı gibi olmuş olabilir burada : Bu 8.4 bir hata üretir rağmen -

Herhangi bir metin türüne (yani metin, varchar (10) vb.) Sahip bir tablo oluşturursanız, sekizlik çıkışları kullanarak bu alana geçersiz bir bayt dizisi ekleyebilirsiniz.

Örneğin, UTF8 kodlu bir veritabanınız varsa şunları yapabilirsiniz:

=> TABLO OLUŞTUR foo (t METİN);

=> DEĞERLERE TAKIN (E '\ 377');

Şimdi, tabloyu kopyalarsanız, sonuçta ortaya çıkan dosyayı tekrar kopyalayamazsınız. Bu, pg_dump yedeklemelerinizin geri yüklenemeyeceği anlamına gelir. Verilerinizi geri almanın tek yolu, bu değerden yeniden kaçmaktır.

Bu mükemmel blogda genel konular ve bunlarla başa çıkmanın bazı yolları hakkında iyi bir yazı var


1

Muhtemelen Unix / Linux ortamınızda kullanılan varsayılan kodlama ile. Şu anda hangi kodlamanın varsayılan kod olduğunu kontrol etmek için aşağıdakileri yürütün:

$ echo $LANG
en_US

Bu durumda, kopya komutunun dayandığı bir UTF-8 kodlaması olmadığını açıkça görebiliriz.

Bunu düzeltmek için, örnek olarak LANG değişkenini aşağıdaki gibi ayarladık:

$ export LANG=en_US.UTF-8

Not: Bu yalnızca geçerli oturum için kullanılabilir. Gelecekteki herhangi bir kabuk oturumunun başlangıcında kullanıma sunmak için ~ / .bashrc veya benzerine ekleyin.

Referans


1

Geçerli karakterleri (örneğin: Çince karakterler) diğer karakterlere dönüştürebildiğinden, düz metin dökümünde iconv'yi körü körüne çalıştırmayı önermiyorum. Aşağıdaki komutu çalıştırarak geçersiz UTF8 karakterini bulmak daha iyidir.

grep -naxv '.*' plain_text_dump.sql

ve sonra belirli veriler üzerinde iconv çalıştırın. Ayrıntılı adım adım açıklama için bu dokümanı kontrol edin .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.