Python:可以转储数据无法加载数据。 Unicode解码错误

Posted

技术标签:

【中文标题】Python:可以转储数据无法加载数据。 Unicode解码错误【英文标题】:Python: Can dumpdata cannot loaddata back. UnicodeDecodeError 【发布时间】:2013-07-24 11:55:21 【问题描述】:

我已经使用 Python 2.7、Django 1.5 和 PostgreSQL 9.2 两个星期了。以前从未见过。一切都是新安装在我的 Windows 7 机器上的,所以它应该有默认设置。 Django 在我的数据库中漂亮地生成表。看起来一切正常。 我可以通过运行从我的数据库中转储数据:

manage.py dumpdata > test.json

manage.py dumpdata  --indent4 > test.json

我看到它看起来应该的 JSON 文件。

然后,我截断一些表并尝试从 JSON 文件中加载它们:

python manage.py loaddata database = T2  test.json    // or without db name

我收到以下错误:

“UnicodeDecodeError: 'utf8' 编解码器无法解码位置 0xff 字节 0:无效的起始字节”

如果我在记事本中打开 test.json 文件,将其保存为utf8 并重试,然后我得到:

“无法解码任何 JSON 对象”

文件看起来还可以,不是空的。

顺便说一句,当我用记事本打开 JSON 文件时,它让我可以将其保存为 Unicode。我的数据库有 UTF8 编码。请指教。谢谢。

【问题讨论】:

不要使用记事本修改代码 显示print(repr(open('test.json', 'rb').read(4))) 【参考方案1】:

对我有用的是以下步骤:

- Open the file in regular notepad
- Select save as
- Select encoding "UTF-8" (Not "UTF-8 (With BOM)")
- Save the file.

现在您可以使用 loaddata。

但是,这仅适用于小到足以让记事本打开的文件。

【讨论】:

在notepad++中通过Encoding -> UTF-8设置utf-8,然后保存【参考方案2】:

0xff 在位置 0 对我来说看起来像是 little-endian UTF-16 byte order marker 的开始。记事本的“Unicode”保存模式是 little-endian UTF-16,因此如果您在创建后从记事本中保存了 json,这很有意义。即使在 utf-8 中,记事本也会保留字节顺序标记,这可能会导致 loaddata 无法解析它。

如果您手头没有未编辑的 json,则需要删除 BOM - 我个人会使用 emacs,但another answer 建议使用此独立的 Windows .exe:

http://www.bryntyounce.com/filebomdetector.htm

【讨论】:

彼得,谢谢您的回复。因为我有 Windows7,所以我不能使用 emacs。我确实安装了您建议的实用程序并运行它。事实上,它表明除了一个被记事本篡改的文件之外的所有文件都是 UTF-16。但是,在运行该实用程序后,我仍然有相同的“UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte” 第 1 步:转换为 UTF-8。第 2 步:删除 BOM。 “我不能使用 emacs,因为我有 Windows7”:是的,你可以。 gnu.org/software/emacs/download.html【参考方案3】:

我在加载数据时遇到了同样的问题。它有编码问题。安装记事本++。并将编码格式更改为UTF-8

在右下角可以看到当前的编码。如果不是 UTF-8,您可以在编码菜单选项卡中简单地将其更改为 UTF-8。

这个解决方案对我有用。

orginal post

【讨论】:

【参考方案4】:

如果您使用的是较新版本的 Windows 10,您可以使用记事本将编码从 UTF-16 更改为 UTF-8,只需再次保存文件并在保存对话框中选择编码选项即可。请参阅下面的示例图片。

【讨论】:

请链接到图片【参考方案5】:

我找到了一种解决此问题的方法,方法是手动重新输出一个新的二进制 json 文件,代码如下,rb 代表“读取和二进制”,wb 代表“写入和二进制”。

首先,进入shell:

python manage.py shell

二、将test.json重写为二进制文件:

with open('path/to/test.json', 'rb') as f:
    data = f.read()
newdata = open('newfile.json', 'wb')
newdata.write(data)
newdata.close()
exit()

然后就可以加载文件了:

python manage.py loaddata newfile.json

以上代码对我有用。希望对你也有帮助。

【讨论】:

以上是关于Python:可以转储数据无法加载数据。 Unicode解码错误的主要内容,如果未能解决你的问题,请参考以下文章

通过python将弹性数据转储到csv或任何NOSQL中

追加到 json 中转储的字典列表,而不用 python 加载列表

从一个非常大的 MySQL 转储文件中以 csv 格式获取数据

Django转储数据/加载数据

脚本化加载文件与转储

执行转储数据时对“错误:无法序列化数据库:”进行故障排除