将 PostgreSQL 数据库的字符编码从 LATIN1 修改为 UTF8 的方法
首先
在新配置的Ubuntu服务器上安装并尝试使用PostgreSQL时,出现了以下错误。
PG::InvalidParameterValue: ERROR: encoding "UTF8" does not match locale "en_US"
DETAIL: The chosen LC_CTYPE setting requires encoding "LATIN1".
当我登录数据库并检查字符编码和区域设置时,结果如下。
$ sudo -u postgres psql
psql (9.5.10)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+---------+-------+-----------------------
postgres | postgres | LATIN1 | en_US | en_US |
template0 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
(3 rows)
哎呀,字符编码变成了LATIN1!
我会介绍如何将在 Ubuntu 服务器上安装的 PostgreSQL 数据库的字符编码更改为 UTF8。需要注意的是,在 CentOS 上,你可以在运行 initdb 命令时添加选项来设置字符编码和本地化设置,请查询相关内容。
环境
-
- Ubuntu 16.04 xenial
- PostgreSQL 9.5.10
步骤
如果PostgreSQL服务正在运行,则停止它。
$ sudo systemctl stop postgresql
接下来,将删除 PostgreSQL 集群。请将您的 PostgreSQL 版本替换为 9.5。根据需要,也可适当替换后续的 9.5。
$ sudo pg_dropcluster --stop 9.5 main
将环境变量语言更改为en_US.UTF-8。
$ export LANGUAGE="en_US.UTF-8"
$ export LANG="en_US.UTF-8"
$ export LC_ALL="en_US.UTF-8"
将先前停止的 PostgreSQL 服务重新启动。
$ sudo systemctl start postgresql
以UTF8字符编码创建PostgreSQL集群。
$ sudo pg_createcluster -e UTF8 --start 9.5 main
如果显示如下,则表示正常。
Creating new cluster 9.5/main ...
config /etc/postgresql/9.5/main
data /var/lib/postgresql/9.5/main
locale en_US.UTF-8
socket /var/run/postgresql
port 5432
Redirecting start request to systemctl
也许不是必要的,但为了谨慎起见,我会重新启动 PostgreSQL 服务。
$ sudo systemctl restart postgresql
让我们来确认一下字符编码是否已经设置为UTF8。
$ sudo -u postgres psql
psql (9.5.10)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(3 rows)
一切没有问题,已经按照预期的初始设置完成了!
概括
我不明白为什么这次使用的服务器的默认设置是LATIN1,因为我以前使用的服务器默认就是UTF8,不需要进行任何修改。
而且,對於 CentOS 來說,可以在執行 initdb 命令時指定選項,所以還可以接受。但對於 Ubuntu 來說,initdb 命令根本不存在。(也就是說,根本不需要執行)
看起来,在Ubuntu上安装PostgreSQL时,字符编码和区域设置会在安装时自动确定,这非常麻烦。
我第一次在搭建 PostgreSQL 环境时遇到了这种情况,但如果对正在面临相似问题的人有所帮助,我会感到很幸运。
请参考
-
- Debian系でPostgreSQLのロケールを変更する
- encoding UTF8 does not match locale en_US; the chosen LC_CTYPE setting requires encoding LATIN1