首页 > 解决方案 > 使用 SQL Server 批量创建后创建重复行

问题描述

我正在进行批量创建以一次将大量信息转储到数据库中。信息是分层的——我创建顶层,然后将数据用作下一层的关系,等等。我无法使用 PostgreSQL,所以在批量处理时我无法利用它返回主键的能力创造。

相反,我创建了一个 UUID 并将其粘贴在每一层中,然后使用它来抓取我刚刚创建的行,以便我可以将它们用于下一层。一个简化的模型如下所示:

class Container(Component):
    parent = models.ForeignKey('self', related_name='children', null=True, blank=True, on_delete=models.CASCADE)
    bulk_insert_id = models.UUIDField(default=uuid.uuid4)

我刚刚创建的批量创建/查询如下所示:

bulk_insert_id = uuid.uuid4()
requirements = []
for requirement, child in zip(self.component['children'], self.children):
    r = models.Container(
        parent=self.db,
        bulk_insert_id=bulk_insert_id,
    )
    child.db_id = r
    requirements.append(r)
models.Container.objects.bulk_create(requirements)
requirements = models.Container.objects.filter(bulk_insert_id=bulk_insert_id)

我遇到的问题是,当我实际使用这些元素时,我发现它们的重复项。就好像批量创建插入了一个副本,然后当我第一次访问/保存数据时会创建另一个副本。这是 SSMS 的示例屏幕截图:

重复行的 SSMS 视图

从上图中可以看出,最后两行是前两行的副本。关于这些重复来自哪里的任何想法?

工具:

标签: pythonsql-serverdjangopython-2.7

解决方案


我发现我做错了什么——我在批量创建之前保存了一个指向容器的陈旧链接。

批量创建它会将行的一份副本放入数据库中。然后,当我使用陈旧的链接(并保存)时,它会放入该行的第二个副本 - 这个没有任何孩子指向它。

解决方案是将陈旧的链接移动到批量创建之后,如下所示:

bulk_insert_id = uuid.uuid4()
requirements = []
for requirement in self.children:
    r = models.Container(
        parent=self.db,
        bulk_insert_id=bulk_insert_id,
    )
    requirements.append(r)
    # don't use the link here, it will be stale when we make the requirements
models.Container.objects.bulk_create(requirements)
requirements = models.Container.objects.filter(bulk_insert_id=bulk_insert_id)
# new stuff
for requirement, child in zip(requirements, self.children):
    child.db_id = requirement

推荐阅读