【问题标题】:Django loaddata with Natural Keys not querying correct Foreign Key带有自然键的 Django loaddata 未查询正确的外键
【发布时间】:2014-02-04 18:08:02
【问题描述】:

这是我的问题。我正在尝试加载一些与另一个模型具有自然键关系的数据。

我修改了父模型以生成自然键。

我使用以下命令从旧数据库中导出数据:

manage.py dumpdata resources.image -n --indent 4 > images.json

然后我尝试使用以下命令导入新数据库:

manage.py loaddata images.json

此时我得到错误:

IntegrityError: Problem installing fixtures: The row in table 'resources_image' 
with primary key '340' has an invalid foreign key: resources_image.voyage_id contains 
a value '41890' that does not have a corresponding value in voyage_voyage.id.

它正在尝试查询 voyage_voyage.id 而不是 get_by_natural_key 函数中指定的 voyage_voyage.voyage_id。我仔细检查了一下,夹具中的密钥在 voyage_id 字段中。下面是我的代码和示例夹具。

父模型:

# for parsing natural key
class VoyageManager(models.Manager):
    def get_by_natural_key(self, voyage_id):
        return self.get(voyage_id=voyage_id)


class Voyage(models.Model):

    # for parsing natural key
    objects = VoyageManager()


    voyage_id = models.IntegerField("Voyage ID (can be empty)", null=True, blank=True)

    # A WHOLE BUNCH OF FIELDS

    # generate natural key
    def natural_key(self):
        return (self.voyage_id)


    class Meta:
        ordering = ['voyage_id',]
        verbose_name = 'Voyage'
        verbose_name_plural = "Voyages"

    def __unicode__(self):
        return "Voyage #%s" % str(self.voyage_id)

儿童模型:

class Image(models.Model):
    voyage = models.ForeignKey(Voyage, null=True, blank=True)

    # MANY OTHER FIELDS

    class Meta:
        verbose_name = "Image"
        verbose_name_plural = "Images"

        ordering = ["date"]

夹具:

{
    "pk": 340, 
    "model": "resources.image", 
    "fields": {
        "category": 56, 
        "voyage": 41890, 
        "date": 1873, 
        "description": "blah blah blah", 
        "language": "  ", 
        "creator": null, 
        "title": "Catherine Zimmermann-Mulgrave, \nc.1873", 
        "source": "blah blah blah", 
        "ready_to_go": true, 
        "file": "images/5AF81DA065049ACE0EC8E236C445F5BC.JPG", 
        "order_num": 0
    }
}

【问题讨论】:

    标签: python django django-fixtures


    【解决方案1】:

    问题是

    {
        "pk": 41890, 
        "model": "voyage.voyage", 
        "fields": {
            ...
        }
    }
    

    在 images.json 文件中,如果不是,我猜你必须以某种方式将它包含在转储中

    【讨论】:

    • voyage.voyage 模型已加载。对于此特定对象,41890 位于 voyage_id 字段中,而不是 voyag.id 字段中。我认为自然键的整个想法是,对于现有数据,pk 可以(并且通常不是静态值)因此可以使用另一个字段来标识记录以将子记录与父记录相关联。
    【解决方案2】:

    这就是我终于想通了

    这个函数期望输入来自一个元组:

    def get_by_natural_key(self, voyage_id):
            return self.get(voyage_id=voyage_id)
    

    当指定 --natural 标志时,此函数生成元组

    def natural_key(self):
            return (self.voyage_id)
    

    这里的技巧是,当你有一个只有一个元素的元组时,它会恢复到它的原始类型(str、int 等)来强制你需要一个尾随“,”的单个元素元组,所以解决方法是:

    def natural_key(self):
            return (self.voyage_id,)
    

    【讨论】:

    • 我不相信上帝......但该死的,上帝保佑你@Alex!
    猜你喜欢
    • 2023-03-14
    • 2019-08-17
    • 2018-07-06
    • 2016-02-06
    • 1970-01-01
    • 2013-05-16
    • 2011-02-01
    • 2018-09-01
    • 1970-01-01
    相关资源
    最近更新 更多