Django 2.0 SQLite3 到 MySQL loaddata 错误:“数据库后端不接受 0 作为 AutoField 的值。”

Posted

技术标签:

【中文标题】Django 2.0 SQLite3 到 MySQL loaddata 错误:“数据库后端不接受 0 作为 AutoField 的值。”【英文标题】:Django 2.0 SQLite3 to MySQL loaddata error: "The database backend does not accept 0 as a value for AutoField." 【发布时间】:2018-08-16 07:06:55 【问题描述】:

我正在尝试将数据库从 sqlite 转移到 mysql

我搜索了这个错误并发现 Stack Overflow 匹配,但还没有看到如何调试/识别有问题的“0 值 AutoField”字段。我尝试通过转储/加载不同的表来解决这个问题,但似乎都产生了相同的错误。

我尝试将-e contenttypes--natural-foreign--natural-primary 附加到我的datadump 命令中,例如,

python manage.py dumpdata -e contenttypes --natural-foreign --natural-primary --indent=4 > datadump_3-7-18.json

运行后python manage.py loaddata --traceback datadump_3-7-18.json

它会产生回溯错误:

(venv) ➜  bikerental git:(additional-features-march) ✗ python manage.py loaddata --traceback datadump_3-7-18.json
Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/rentals/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "/rentals/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/rentals/venv/lib/python3.6/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/rentals/venv/lib/python3.6/site-packages/django/core/management/base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "/rentals/venv/lib/python3.6/site-packages/django/core/management/commands/loaddata.py", line 72, in handle
    self.loaddata(fixture_labels)
  File "/rentals/venv/lib/python3.6/site-packages/django/core/management/commands/loaddata.py", line 113, in loaddata
    self.load_label(fixture_label)
  File "/rentals/venv/lib/python3.6/site-packages/django/core/management/commands/loaddata.py", line 177, in load_label
    obj.save(using=self.using)
  File "/rentals/venv/lib/python3.6/site-packages/django/core/serializers/base.py", line 205, in save
    models.Model.save_base(self.object, using=using, raw=True, **kwargs)
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/base.py", line 759, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/base.py", line 842, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/base.py", line 880, in _do_insert
    using=using, raw=raw)
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/query.py", line 1125, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1280, in execute_sql
    for sql, params in self.as_sql():
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1233, in as_sql
    for obj in self.query.objs
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1233, in <listcomp>
    for obj in self.query.objs
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1232, in <listcomp>
    [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1172, in prepare_value
    value = field.get_db_prep_save(value, connection=self.connection)
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 767, in get_db_prep_save
    return self.get_db_prep_value(value, connection=connection, prepared=False)
  File "/rentals/venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 940, in get_db_prep_value
    value = connection.ops.validate_autopk_value(value)
  File "/rentals/venv/lib/python3.6/site-packages/django/db/backends/mysql/operations.py", line 163, in validate_autopk_value
    raise ValueError('The database backend does not accept 0 as a '
ValueError: Problem installing fixture '/rentals/bikerental/datadump_3-7-18.json': The database backend does not accept 0 as a value for AutoField.

我注意到这似乎与外键值有关,所以我将发布我拥有的:

bike = models.ManyToManyField(Bike, blank=True)

有什么方法可以更轻松地识别我认为这是来自数据库的哪个位置?

【问题讨论】:

我通过手动编辑数据转储解决了这个问题。在ManyToManyField 引用的表中,有一条ID 为0 的记录。这是由于我最初手动输入的记录集,从 0 开始递增。删除此记录并在 ManyToManyField 中删除对它的引用允许 loaddata 命令正常工作。作为记录,我只想声明错误处理可以/应该通过更明确来改进,因为它让我几乎一整天都在摸不着头脑。 您应该添加该评论作为答案 - 这很有趣。 @Shadow 啊,是的。我将。谢谢。 【参考方案1】:

我通过手动编辑数据转储解决了这个问题。在ManyToManyField所引用的表中,有一条ID为0的记录。这是由于我最初手动输入的记录集,从 0 开始递增。删除此记录并在 ManyToManyField 中删除对它的引用允许 loaddata 命令正常工作。作为记录,我只想声明错误处理可以/应该通过更明确来改进,因为它让我几乎一整天都在摸不着头脑。

用于说明datadump_3-7-18.json

                                 <----- I GOT DELETED  
    "model": "inventory.bike",    <----- I GOT DELETED  
    "pk": 0,                      <----- I GOT DELETED  
    "fields":                    <----- I GOT DELETED   
       ...                        <----- I GOT DELETED  
                                 <----- I GOT DELETED  
,                                <----- I GOT DELETED  

    "model": "inventory.bike",
    "pk": 1,
    "fields": 
       ...
    
,

    "model": "inventory.bike",
    "pk": 2,
    "fields": 
       ...
    
,

稍后在datadump_3-7-18.json 中,包含0 ManyToManyField 外键的记录:


    "model": "reservations.reservation",
    "pk": 55,
    "fields": 
       ...
        "bike": [
            0,      <----- I GOT DELETED   
            1,
            2
        ]
    
,

    "model": "reservations.reservation",
    "pk": 28,
    "fields": 
        ...
        "bike": [
            0,      <----- I GOT DELETED  
            1,
            2,
            3
        ]
    
,

【讨论】:

以上是关于Django 2.0 SQLite3 到 MySQL loaddata 错误:“数据库后端不接受 0 作为 AutoField 的值。”的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中将 SQLite3 数据库迁移到 MySQL

将 Django 数据库:SQLITE3 更改为 MARIADB

加载数据转储时,将 Django 项目从 sqlite3 后端切换到 postgresql 失败

django 10.5 sqlite3迁移到mysql

在 CakePHP 2.0 中使用 SQLite3

搭建 python 3.5+pycharm 2017.1.3+django 1.12.0 首次 将sqlite3 迁移到mysql