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

Django通过call_command调用dumpdata失败 报ASCII编码错误

问题描述

需要通过编程方式调用Django内置的dumpdata命令,初始调用代码如下:

from django.core.management import call_command
call_command('dumpdata', 'asdf', indent=2, output=filePath)

代码执行失败,抛出错误:
Unable to serialize database: 'ascii' codec can't encode character '\xdf' in position 83: ordinal not in range(128)
但直接在终端执行如下命令可以正常运行:
python3 manage.py dumpdata --indent=2 --output=dump.json.gz asdf
需要定位call_command()方式调用失败的具体原因。

运行环境
  • Python版本:3.6.9
  • Django版本:3.2.13
  • 环境变量$LANG配置:en_US.UTF-8
  • 环境变量$LC_ALL配置:en_US.UTF-8
  • 环境变量$LC_CTYPE配置:UTF-8
故障原因

报错本质是文件写入时的编码不匹配:

  1. Django 3.2版本的dumpdata命令接收到output参数传入的文件路径时,会直接调用内置open()方法打开文件,且没有显式指定文件编码,此时Python会使用当前进程的默认首选编码(即locale.getpreferredencoding()的返回值)作为文件写入编码。
  2. 终端直接执行命令时,当前会话正确加载了UTF-8的locale配置,locale.getpreferredencoding()返回UTF-8,可以正常序列化包含非ASCII字符(报错中的\xdf是德语小写字母ß)的数据。
  3. 通过代码调用call_command()时,进程通常是web服务、后台任务、定时任务这类没有绑定交互终端的场景,不会正确继承shell的locale环境变量,导致locale.getpreferredencoding()回退到ASCII编码,遇到非ASCII字符时就会抛出编码错误。
修复方案

不要将文件路径传入output参数,改为自行以UTF-8编码打开文件对象,传入call_command的stdout参数即可,和终端执行逻辑完全对齐:

import gzip
from django.core.management import call_command

# 输出为普通json文件
with open("dump.json", "w", encoding="utf-8") as f:
    call_command("dumpdata", "asdf", indent=2, stdout=f)

# 输出为gzip压缩的json文件,和终端执行.gz输出的逻辑一致
with gzip.open("dump.json.gz", "wt", encoding="utf-8") as f:
    call_command("dumpdata", "asdf", indent=2, stdout=f)

该写法绕开了Django自动打开文件时依赖进程默认编码的逻辑,全场景强制使用UTF-8编码写入,不会再触发ASCII编码报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:36:22