Postgres veritabanının karakter kodlamasını nasıl değiştirirsiniz?


Yanıtlar:


64

Veritabanınızın kodlamasını değiştirmek için:

  1. Veritabanınızı boşaltın
  2. Veritabanınızı bırakın,
  3. Farklı kodlamayla yeni veritabanı oluşturun
  4. Verilerinizi yeniden yükleyin.

Tüm bunlar sırasında istemci kodlamasının doğru ayarlandığından emin olun.

Kaynak: http://archives.postgresql.org/pgsql-novice/2006-03/msg00210.php


Bağlantıdan anlamadığım şey şu: "İlk adımda oluşturulan döküm dosyasında herhangi bir özel karakter olup olmadığını kontrol edin ve gerekli değişiklikleri yapın" => Tüm özel karakterleri manuel olarak değiştirmem gerekiyor mu
spankmaster79

1
Cevabınıza dökmek ve yeniden içe aktarmak için komutları ekleyebilir misiniz? like sudo -u postgres pg_dump your_db > /backups/postgresql.sql...
rubo77

104

Öncelikle Daniel'in cevabı doğru ve güvenli seçenektir.

SQL_ASCII'den başka bir şeye geçişin özel durumu için, hile yapabilir ve veritabanı kodlamasını yeniden atamak için pg_database kataloğunu dürtebilirsiniz. Bu, beklenen kodlamada ASCII olmayan karakterleri zaten depoladığınızı (veya hiçbir ASCII olmayan karakter kullanmadığınızı) varsayar.

O zaman şunları yapabilirsiniz:

update pg_database set encoding = pg_char_to_encoding('UTF8') where datname = 'thedb'

Bu, veritabanının harmanlamasını değiştirmeyecek, kodlanmış baytların karakterlere nasıl dönüştürüldüğünü değiştirmeyecek (bu nedenle şimdi length('£123')5 yerine 4 döndürecektir). Veritabanı 'C' harmanlamasını kullanıyorsa, ASCII dizeleri için sıralamada herhangi bir değişiklik olmamalıdır. Yine de, ASCII olmayan karakterler içeren herhangi bir dizini yeniden oluşturmanız gerekecektir.

Uyarı imparatoru. Damping ve yeniden yükleme, veritabanı içeriğinizin aslında beklediğiniz kodlamada olup olmadığını kontrol etmenin bir yolunu sağlar ve bu olmaz. Ve eğer veritabanında bazı yanlış kodlanmış verileriniz olduğu ortaya çıkarsa, kurtarmak zor olacaktır. Yani eğer yapabilirseniz, boşaltın ve yeniden başlatın.


1
+1 Teşekkürler. Geliştirme makinem UTF8 kodlama kullanıyor ancak üretimim LATIN1 kullanıyor. Bu yüzden birçok hata yapıyordum.
Luiz Damim

1
Bana şu hatayı veriyor: -bash: syntax error near unexpected token (''
Abhipso Ghosh

@AbhipsoGhosh bunun bir bash kabuğuna değil, psqlkomut isteminde yapıştırılması gerekiyor .
Pierre

14

Bir veritabanının belirli bir kodlamayla dökümünü alıp başka bir veritabanında farklı bir kodlamayla geri yüklemeyi denemek, verilerin bozulmasına neden olabilir. Veri kodlaması, veri tabanına herhangi bir veri girilmeden ÖNCE ayarlanmalıdır.

Kontrol bu : o bozuk verilere yol olabilir çünkü başka bir veritabanı kopyalarken, kodlama ve yerel ayarları, kaynak veritabanının olanlardan değiştirilemez.

Ve bu : Bazı yerel kategorilerin, veritabanı oluşturulduğunda değerlerinin sabitlenmiş olması gerekir. Farklı veritabanları için farklı ayarlar kullanabilirsiniz, ancak bir veritabanı oluşturulduktan sonra bunları artık o veritabanı için değiştiremezsiniz. LC_COLLATE ve LC_CTYPE bu kategorilerdir. Dizinlerin sıralama düzenini etkilerler, bu nedenle sabit tutulmaları gerekir, aksi takdirde metin sütunlarındaki dizinler bozulabilir. ( Ancak, Bölüm 22.2'de tartışıldığı gibi bu kısıtlamayı harmanlamaları kullanarak hafifletebilirsiniz. ) Bu kategoriler için varsayılan değerler, initdb çalıştırıldığında belirlenir ve bu değerler, CREATE DATABASE komutunda aksi belirtilmedikçe, yeni veritabanları oluşturulduğunda kullanılır.


Debian işletim sisteminizde doğru bir yerel kodlama ile baştan itibaren her şeyi burada açıklandığı gibi yeniden inşa etmeyi tercih ederim :

su root

Yerel ayarlarınızı yeniden yapılandırın:

dpkg-reconfigure locales

Yerel ayarınızı seçin (örneğin İsviçre'de Fransızca için: fr_CH.UTF8)

Postgresql'i düzgün bir şekilde kaldırın ve temizleyin:

apt-get --purge remove postgresql\*
rm -r /etc/postgresql/
rm -r /etc/postgresql-common/
rm -r /var/lib/postgresql/
userdel -r postgres
groupdel postgres

Postgresql'i yeniden yükleyin:

aptitude install postgresql-9.1 postgresql-contrib-9.1 postgresql-doc-9.1

Artık herhangi bir yeni veritabanı doğru kodlama, LC_TYPE (karakter sınıflandırması) ve LC_COLLATE (dize sıralama düzeni) ile otomatik olarak oluşturulacaktır.


2
Sanırım "dpkg-refigure locales", çoğul. Tekil biçim işe yaramıyor gibi görünüyor (sadece kontrol edildi).
foo

9

Daniel Kutik'in cevabı doğru, ancak veritabanının yeniden adlandırılmasıyla daha da güvenli olabilir .

Yani, gerçekten güvenli yol şudur:

  1. Farklı kodlama ve adla yeni veritabanı oluşturun
  2. Veritabanınızı boşaltın
  3. Dökümü yeni DB'ye geri yükle
  4. Uygulamanızın yeni DB ile doğru şekilde çalıştığını test edin
  5. Eski DB'yi anlamlı bir şekilde yeniden adlandırın
  6. Yeni DB'yi yeniden adlandırın
  7. Uygulamayı tekrar test edin
  8. Eski veritabanını bırak

Acil durumda, DB'leri yeniden adlandırmanız yeterli


7
# dump into file
pg_dump myDB > /tmp/myDB.sql

# create an empty db with the right encoding (on older versions the escaped single quotes are needed!)
psql -c 'CREATE DATABASE "tempDB" WITH OWNER = "myself" LC_COLLATE = '\''de_DE.utf8'\'' TEMPLATE template0;'

# import in the new DB
psql -d tempDB -1 -f /tmp/myDB.sql

# rename databases
psql -c 'ALTER DATABASE "myDB" RENAME TO "myDB_wrong_encoding";' 
psql -c 'ALTER DATABASE "tempDB" RENAME TO "myDB";'

# see the result
psql myDB -c "SHOW LC_COLLATE"   
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.