Django有多对多数据重复?

时间:2017-09-19 14:01:23

标签: django postgresql database-design

背景

我存储有关研究人员的数据。例如,研究人员简介,每位研究人员的指标,他们发表的期刊,他们的论文等等。

问题

我目前的数据库设计是这样的: enter image description here

每位研究员都有许多期刊(他们发表在中)。期刊有关于它的信息。 同样适用于主题领域

但目前,这会导致大量数据重复。例如,同一期刊可以在期刊表中多次出现,只是链接到不同的研究人员等。

有没有更好的方法来解决这个问题?就像现在一样,我在期刊栏目中有超过5000行,但只有约1000种期刊。

谢谢!

编辑:这可能是由于我为新数据保存模型的方式(如下所述)。任何人都可以提供正确的方法来循环并将哈希保存到模型中吗?

模型 - 研究员

class Researcher(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    scopus_id = models.BigIntegerField(db_index=True) # Index to make searches quicker
    academic_rank = models.CharField(max_length=100)
    title = models.CharField(max_length=200,default=None, blank=True, null=True)
    salutation = models.CharField(max_length=200,default=None, blank=True, null=True)
    scopus_first_name = models.CharField(max_length=100)
    scopus_last_name = models.CharField(max_length=100)
    affiliation = models.CharField(default=None, blank=True, null=True,max_length = 255)
    department = models.CharField(default=None, blank=True, null=True,max_length = 255)
    email = models.EmailField(default=None, blank=True, null=True)
    properties = JSONField(default=dict)

    def __str__(self):
        return "{} {}, Scopus ID {}".format(self.scopus_first_name,self.scopus_last_name,self.scopus_id)

模特 - 期刊

class Journal(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    researchers =  models.ManyToManyField(Researcher)
    title = models.TextField()
    journal_type = models.CharField(max_length=40,default=None,blank=True, null=True)
    abbreviation = models.TextField(default=None, blank=True, null=True)
    issn = models.CharField(max_length=50, default=None, blank=True, null=True)
    journal_rank = models.IntegerField(default=None, blank=True, null=True)
    properties = JSONField(default=dict)

    def __str__(self):
        return self.title

我目前如何保存它们:

db_model_fields = {'abbreviation': 'Front. Artif. Intell. Appl.',
 'issn': '09226389',
 'journal_type': 'k',
 'researchers': <Researcher:  x, Scopus ID f>,
 'title': 'Frontiers in Artificial Intelligence and Applications'}
# remove researchers or else create will fail (some id need to exist error)
researcher = db_model_fields["researchers"]
del db_model_fields["researchers"]
model_obj = Journal(**db_model_fields)
model_obj.save()
model_obj.researchers.add(researcher)
model_obj.save()

1 个答案:

答案 0 :(得分:0)

以下是它的工作原理:

class Journal(models.Model):
    # some fields

class Researcher(models.Model):
    # some fields
    journal = models.ManyToManyField(Journal)

Django将创建一个关系表:

  

在幕后,Django创建了一个中间连接表来表示多对多关系

所以你在这个表中有很多行,这是它的工作原理,但是THEIR表中的journal实例和researcher实例将是唯一的。

您的错误可能来自您的保存方式。而不是:

model_obj = Journal(**db_model_fields)
model_obj.save()

尝试这样做:

model_obj = Journal.objects.get_or_create(journal_id)

这样,如果已经存在,您将获得它。由于您的任何字段都不是唯一的,因此您可以创建新的日记,但是没有问题,因为每当您添加新日记时,django都会生成唯一的ID。