首页 文章

在Django中加载fixture时出现contenttypes的问题

提问于
浏览
96

由于内容类型冲突,我无法将Django fixtures加载到我的MySQL数据库中 . 首先,我尝试从我的应用程序转储数据,如下所示:

./manage.py dumpdata escola > fixture.json

但我不断错过外键问题,因为我的应用程序“escola”使用其他应用程序中的表 . 我一直在添加额外的应用程序,直到我这样做:

./manage.py dumpdata contenttypes auth escola > fixture.json

现在,当我尝试将数据作为测试夹具加载时,问题是以下约束违规:

IntegrityError: (1062, "Duplicate entry 'escola-t23aluno' for key 2")

似乎问题是Django正在尝试动态地重新创建具有与夹具中的主键值冲突的不同主键值的内容类型 . 这似乎与此处记录的错误相同:http://code.djangoproject.com/ticket/7052

问题是推荐的解决方法是转储我正在做的contenttypes应用程序!?是什么赋予了?如果它有任何区别,我确实有一些自定义模型权限,如下所示:http://docs.djangoproject.com/en/dev/ref/models/options/#permissions

12 回答

  • 1

    manage.py dumpdata --natural 将使用更持久的外键表示 . 在django,他们被称为"natural keys" . 例如:

    • Permission.codename 用于支持 Permission.id

    • User.username 用于支持 User.id

    阅读更多:natural keys section in "serializing django objects"

    dumpdata 的其他一些有用的参数:

    • --indent=4 使其具有人类可读性 .

    • -e sessions 排除会话数据

    • -e admin 排除管理员网站上管理员操作的历史记录

    • -e contenttypes -e auth.Permission 排除每次在 syncdb 期间从架构自动重新创建的对象 . 只能与 --natural 一起使用,否则最终可能会出现严重对齐的ID号 .

  • 30

    是的,这真的很烦人 . 有一段时间我通过在加载fixture之前对contenttypes应用程序执行“manage.py reset”来解决这个问题(以摆脱与转储版本不同的自动生成的contenttypes数据) . 这很有效,但最终我厌倦了麻烦,完全放弃了直接的SQL转储(当然,你丢失了数据库的可移植性) .

    update - 最好的答案是使用 --natural 标志 dumpdata ,如下面的答案所示 . 当我写这个答案时,那个标志还不存在 .

  • 9

    尝试在创建fixture时跳过contenttypes:

    ./manage.py dumpdata --exclude contenttypes > fixture.json
    

    它在类似的单元测试情况下对我有用,你对内容类型的洞察力确实有帮助!

  • 1

    这里的答案都是旧的...截至2017年,最佳答案是:

    manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4
    
  • 6

    我在测试用例中通过在加载转储文件之前从单元测试重置contenttypes应用程序解决了这个问题 . Carl建议使用 manage.py 命令,我只使用 call_command 方法做同样的事情:

    >>> from django.core import management
    >>> management.call_command("flush", verbosity=0, interactive=False)
    >>> management.call_command("reset", "contenttypes", verbosity=0, interactive=False)
    >>> management.call_command("loaddata", "full_test_data.json", verbosity=0)
    

    我的 full_test_data.json fixture包含与其余测试数据相对应的contenttypes应用转储 . 通过在加载前重置应用程序,它可以防止重复键 IntegrityError .

  • 23

    我没有使用MySQL,而是将一些数据从实时服务器导入sqlite . 在执行 loaddata 之前清除 contenttypes app数据可以解决问题:

    from django.contrib.contenttypes.models import ContentType
    ContentType.objects.all().delete()
    quit()
    

    然后

    python manage.py loaddata data.json
    
  • 129
    python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth.Permission --exclude=admin.logentry --exclude=sessions.session --indent 4 > initial_data.json
    

    这适合我 . 在这里,我排除了实际模型的一切 .

    • 如果您看到除了您创建的模型之外的任何其他模型,您可以安全地排除这些模型 . 这种方法的一个缺点是您在日志数据和auth数据上都会松动 .
  • 33

    我将给出另一个我刚才想出的答案 . 也许它会帮助OP,也许它会帮助别人 .

    我有一个多对多的关系表 . 它有一个主键和其他表的两个外键 . 我发现如果我在夹具中有一个条目,其中两个外键与表中已有不同pk的另一个条目相同,则它将失败 . M2M关系表对于两个外键具有"unique together" .

    因此,如果它是一个正在破坏的M2M关系,请查看它添加的外键,查看您的数据库以查看该对FK是否已经列在不同的PK下 .

  • 0

    真的,真的很烦人......我每次都被这个咬了 .

    我尝试使用--exclude contenttypes和--natural dumpdata,我总是遇到问题..

    对我来说最有效的方法就是在syncdb之后执行 truncate table django_content_type; 然后加载数据 .

    当然,对于initial_data.json,自动加载你是一个秋天 .

  • 1

    我有时遇到过类似的错误 . 事实证明我是在创建必要的表之前尝试加载灯具 . 所以我做了:

    $ python manage.py makemigrations
    $ python manage.py migrate
    $ python manage.py loaddata fixtures/initial_data.json
    

    它就像一个魅力

  • 1
    ./manage.py dumpdata app.Model --natural-foreign
    

    将改变

    "content_type": 123
    

    "content_type": [
        "app_label",
        "model"
      ],
    

    夹具适用于 TestCase

  • 10

    您需要使用自然键来表示任何外键和多对多关系 . 此外,排除 sessions 应用程序中的 session 表和 admin 应用程序中的 logentry 表可能是个好主意 .

    Django 1.7+

    python manage.py dumpdata --natural-foreign --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
    

    Django <1.7

    python manage.py dumpdata --natural --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
    

    根据Django documentation,版本1.7中已弃用 --natural ,因此应使用选项 --natural-foreign .

    您还可以省略此对象的序列化数据中的主键,因为可以在反序列化期间通过传递 --natural-primary 标志来计算它 .

    python manage.py dumpdata --natural-foreign --natural-primary --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
    

相关问题