unicode 的 Django loaddata 失败
Django loaddata fails for unicode
这是模型:
class ListItem(models.Model):
# id -- PK
dateCreated = models.DateTimeField(auto_now_add=True)
dateModified = models.DateTimeField(auto_now_add=True)
listId = models.IntegerField(null=False) # required FK => List
itemId = models.CharField(max_length=8, null=False)
description = models.CharField(max_length=1024)
notes = models.CharField(max_length=2048)
class Meta:
ordering = ('itemId',)
这里是夹具文件 (json) 中的违规项:
{
"model": "myproject.ListItem",
"pk": 721,
"fields": {
"listId": 26,
"itemId": "A3",
"description": "Statystyka Książek Papierowych, Mówionych I Elektronicznych",
"notes": "Polish Statistical Book and E-book Classification",
"dateCreated": "2018-05-14 22:05:25",
"dateModified": "2018-05-14 22:05:25"
}
}, ...
这是我用来尝试加载数据的命令:
python3 manage.py loaddata listItems.json
导致以下错误:
django.db.utils.OperationalError: Problem installing fixture \
'/Users/sloughin/dev/myproject/fixtures/listItems.json': \
Could not load myproject.ListItem(pk=721): \
(1366, "Incorrect string value: '\xC4\x85\xC5\xBCek...' \
for column 'description' at row 1")
我是否应该在模型中使用一些标志来指示我希望该字段包含 unicode 数据?
这是 运行 针对 Ubuntu 16.04 上的 MySQL 数据库,我在 iMac 上 运行 python 3.6.2(OSX 10.13.5)。我的所有其他加载数据操作都运行良好。
好的,我想我明白了。 MySQL 数据库 VARCHAR 字段默认为 utf8,它支持大多数(但不是全部)unicode 字符。这就是为什么有些记录可以,有些则不行。你必须使用 utf8mb4 而不是 utf8。这增加了数据库字段的宽度,因为它们现在每个字符使用 4 个字节而不是 3 个字节,(因此对于某些 DBMS,您可能还需要将模型中字段的宽度扩大 4/3 倍)虽然我m 告诉 MySQL 字段以字符而非字节指定。
但是,我们需要有一个新的迁移文件才能使用,所以我要将其中一个字段更改为一个字符长。
class ListItem(models.Model):
# id -- PK
dateCreated = models.DateTimeField(auto_now_add=True)
dateModified = models.DateTimeField(auto_now_add=True)
listId = models.IntegerField(null=False) # required FK => List
itemId = models.CharField(max_length=8, null=False)
description = models.CharField(max_length=1025) # was 1024
notes = models.CharField(max_length=2048)
我重新跑了python3 manage.py makemigrations
接下来,我转到迁移文件夹并编辑新的迁移文件(我的文件名为 002_auto_20180619_1849.py),其中包含 class Migrations:
,其中定义了 operations
。您会看到 AlterField 操作使字段变宽,但之后您可以附加额外的 SQL 操作,如下所示:
migrations.AlterField(...),
migrations.RunSQL(
'alter table myproject_listitem CONVERT TO CHARACTER SET
utf8mb4 COLLATE utf8mb4_unicode_ci;'),
migrations.RunSQL(
'alter table myproject_listitem CONVERT TO CHARACTER SET
utf8mb4 COLLATE utf8mb4_unicode_ci;'),
migrations.RunSQL(
'alter table myproject_listitem change description description
VARCHAR(1366) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'),
migrations.RunSQL(
'alter table myproject_listitem change notes notes
VARCHAR(2731) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'),
在这里,我将每个 SQL 语句分成两行,以便您阅读。如果您可以直接访问数据库,您也可以在 mysql 会话中执行此操作,但我想知道如何在迁移过程中执行此操作。
在你运行这个迁移之前,检查以确保你已经sqlparse
安装。如果没有,则 pip3 install sqlparse
或将其包含在您的虚拟环境或 docker 容器中作为要求。那么:
python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, myproject, sessions
Running migrations:
Applying myproject.0002_auto_20180619_1849... OK
在那之后,我能够 运行 python3 manage.py loaddata listItems.json
并且一切正常!
这是模型:
class ListItem(models.Model):
# id -- PK
dateCreated = models.DateTimeField(auto_now_add=True)
dateModified = models.DateTimeField(auto_now_add=True)
listId = models.IntegerField(null=False) # required FK => List
itemId = models.CharField(max_length=8, null=False)
description = models.CharField(max_length=1024)
notes = models.CharField(max_length=2048)
class Meta:
ordering = ('itemId',)
这里是夹具文件 (json) 中的违规项:
{
"model": "myproject.ListItem",
"pk": 721,
"fields": {
"listId": 26,
"itemId": "A3",
"description": "Statystyka Książek Papierowych, Mówionych I Elektronicznych",
"notes": "Polish Statistical Book and E-book Classification",
"dateCreated": "2018-05-14 22:05:25",
"dateModified": "2018-05-14 22:05:25"
}
}, ...
这是我用来尝试加载数据的命令:
python3 manage.py loaddata listItems.json
导致以下错误:
django.db.utils.OperationalError: Problem installing fixture \
'/Users/sloughin/dev/myproject/fixtures/listItems.json': \
Could not load myproject.ListItem(pk=721): \
(1366, "Incorrect string value: '\xC4\x85\xC5\xBCek...' \
for column 'description' at row 1")
我是否应该在模型中使用一些标志来指示我希望该字段包含 unicode 数据?
这是 运行 针对 Ubuntu 16.04 上的 MySQL 数据库,我在 iMac 上 运行 python 3.6.2(OSX 10.13.5)。我的所有其他加载数据操作都运行良好。
好的,我想我明白了。 MySQL 数据库 VARCHAR 字段默认为 utf8,它支持大多数(但不是全部)unicode 字符。这就是为什么有些记录可以,有些则不行。你必须使用 utf8mb4 而不是 utf8。这增加了数据库字段的宽度,因为它们现在每个字符使用 4 个字节而不是 3 个字节,(因此对于某些 DBMS,您可能还需要将模型中字段的宽度扩大 4/3 倍)虽然我m 告诉 MySQL 字段以字符而非字节指定。
但是,我们需要有一个新的迁移文件才能使用,所以我要将其中一个字段更改为一个字符长。
class ListItem(models.Model):
# id -- PK
dateCreated = models.DateTimeField(auto_now_add=True)
dateModified = models.DateTimeField(auto_now_add=True)
listId = models.IntegerField(null=False) # required FK => List
itemId = models.CharField(max_length=8, null=False)
description = models.CharField(max_length=1025) # was 1024
notes = models.CharField(max_length=2048)
我重新跑了python3 manage.py makemigrations
接下来,我转到迁移文件夹并编辑新的迁移文件(我的文件名为 002_auto_20180619_1849.py),其中包含 class Migrations:
,其中定义了 operations
。您会看到 AlterField 操作使字段变宽,但之后您可以附加额外的 SQL 操作,如下所示:
migrations.AlterField(...),
migrations.RunSQL(
'alter table myproject_listitem CONVERT TO CHARACTER SET
utf8mb4 COLLATE utf8mb4_unicode_ci;'),
migrations.RunSQL(
'alter table myproject_listitem CONVERT TO CHARACTER SET
utf8mb4 COLLATE utf8mb4_unicode_ci;'),
migrations.RunSQL(
'alter table myproject_listitem change description description
VARCHAR(1366) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'),
migrations.RunSQL(
'alter table myproject_listitem change notes notes
VARCHAR(2731) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'),
在这里,我将每个 SQL 语句分成两行,以便您阅读。如果您可以直接访问数据库,您也可以在 mysql 会话中执行此操作,但我想知道如何在迁移过程中执行此操作。
在你运行这个迁移之前,检查以确保你已经sqlparse
安装。如果没有,则 pip3 install sqlparse
或将其包含在您的虚拟环境或 docker 容器中作为要求。那么:
python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, myproject, sessions
Running migrations:
Applying myproject.0002_auto_20180619_1849... OK
在那之后,我能够 运行 python3 manage.py loaddata listItems.json
并且一切正常!