You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中显示波兰字符及解决Django数据库解码错误

解决Django原生SQL查询波兰字符时的UnicodeDecodeError

这个问题我之前帮朋友排查过,大概率是数据库字符集的配置没完全统一导致的——尤其是MySQL里的utf8有个容易踩的坑,咱们一步步来解决:

1. 先确认数据库/表/列的实际字符集

首先得搞清楚你的数据库、目标表和那个varchar列,是不是真的用了正确的UTF-8编码(MySQL里推荐用utf8mb4,它是完整的UTF-8,而默认的utf8其实是utf8mb3,只支持部分Unicode字符)。

登录数据库,执行这几条SQL检查:

-- 查看数据库默认字符集
SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = '你的数据库名';

-- 查看目标表的字符集
SELECT table_collation FROM information_schema.TABLES WHERE table_schema = '你的数据库名' AND table_name = '你的表名';

-- 查看目标列的字符集
SELECT column_name, character_set_name, collation_name FROM information_schema.COLUMNS WHERE table_schema = '你的数据库名' AND table_name = '你的表名' AND column_name = '你的列名';

如果列的字符集不是utf8或utf8mb4,赶紧修改:

ALTER TABLE 你的表名 MODIFY COLUMN 你的列名 VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

(优先用utf8mb4,避免以后遇到其他特殊字符再出问题)

2. 配置Django的数据库连接字符集

就算数据库本身是UTF-8,如果Django和数据库的连接没指定正确的字符集,也会出现解码错误。打开settings.py,在DATABASES配置里加上OPTIONS:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '你的数据库名',
        'USER': '你的用户名',
        'PASSWORD': '你的密码',
        'HOST': 'localhost',
        'PORT': '3306',
        'OPTIONS': {
            'charset': 'utf8mb4',
            'use_unicode': True,
        },
    }
}

如果用的是mysqlclient(现在Django推荐的MySQL驱动),charset设置就足够;如果是旧的MySQLdb,use_unicode=True也得加上。

3. 检查数据本身的编码是否正确

如果之前这个列用的是其他编码(比如波兰常用的latin2),直接改字符集可能会导致乱码。这种情况得先导出数据转码再导入:

  1. 导出数据时指定原编码(比如latin2):
    mysqldump -u 用户名 -p --default-character-set=latin2 你的数据库名 你的表名 > data.sql
    
  2. 把数据转成utf8mb4编码:
    iconv -f latin2 -t utf8mb4 data.sql > data_utf8.sql
    
  3. 先备份好原数据,然后清空表、修改表/列字符集为utf8mb4,最后导入转码后的数据:
    mysql -u 用户名 -p --default-character-set=utf8mb4 你的数据库名 < data_utf8.sql
    

4. 原生SQL查询时的临时处理

如果前面几步都做了还是有问题,试试在原生查询前先设置连接的字符集:

from django.db import connection

def your_view(request):
    with connection.cursor() as cursor:
        # 先强制设置连接字符集
        cursor.execute("SET NAMES utf8mb4;")
        # 再执行你的查询
        cursor.execute("SELECT 你的列名 FROM 你的表名;")
        rows = cursor.fetchall()
        # 确保结果是正确的字符串
        results = [row[0] if isinstance(row[0], str) else row[0].decode('utf8mb4') for row in rows]
    # 后续业务逻辑
    ...

最后提醒个误区

你加的# -- coding: utf-8 --只是告诉Python解释器这个视图文件本身的编码,和数据库交互的编码完全没关系,不用纠结这个配置~

内容的提问来源于stack exchange,提问作者vba_user

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:41:44