在数据库中已经存在数据库后添加了UUID字段。有没有办法填充现有数据的UUID字段? [英] UUID field added after data already in database. Is there any way to populate the UUID field for existing data?

查看:407
本文介绍了在数据库中已经存在数据库后添加了UUID字段。有没有办法填充现有数据的UUID字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经向我的一些模型添加了一个UUID字段,然后与South一起迁移。我创建的任何新对象的UUID字段填充正确。但是,我所有旧数据中的UUID字段为空。

I've added a UUID field to some of my models and then migrated with South. Any new objects I create have the UUID field populated correctly. However the UUID fields on all my older data is null.

有没有办法填充现有数据的UUID数据?

Is there any way to populate UUID data for existing data?

推荐答案

p>对于以下示例类:

For the following sample class:

from django_extensions.db.fields import UUIDField

def MyClass:
    uuid = UUIDField(editable=False, blank=True)
    name = models.CharField()

如果您使用South,请创建数据迁移:

If you're using South, create a data migration:

python ./manage.py datamigration <appname> --auto

然后使用以下代码更新具有特定逻辑的迁移以添加UUID :

And then use the following code to update the migration with the specific logic to add a UUID:

from django_extensions.utils import uuid

def forwards(self, orm):
    for item in orm['mypp.myclass'].objects.all():
        if not item.uuid:
            item.uuid = uuid.uuid4() #creates a random GUID
            item.save()


def backwards(self, orm):
    for item in orm['mypp.myclass'].objects.all():
        if item.uuid:
            item.uuid = None
            item.save()

您可以创建不同类型的UUID,每个UUID都以不同的方式生成。 Django-extensions中的 uuid.py模块具有您可以创建的UUID类型的完整列表。

You can create different types of UUIDs, each generated differently. the uuid.py module in Django-extensions has the complete list of the types of UUIDs you can create.

重要的是要注意,如果在具有大量对象的环境中运行此迁移,它有可能超时(例如,如果使用fabric来部署)。在生产环境中,需要填充现有字段的一种替代方法。

It's important to note that if you run this migration in an environment with a lot of objects, it has the potential to time out (for instance, if using fabric to deploy). An alternative method of filling in already existing fields will be required for production environments.

尝试将其用于大量对象时,可能会耗尽内存我们发现自己的内存不足,部署失败了17,000多个对象)。

It's possible to run out of memory while trying to do this to a large number of objects (we found ourselves running out of memory and having the deployment fail with 17,000+ objects).

为了解决这个问题,你需要在您的迁移(或棒)中创建一个自定义迭代器它在哪里真的很有用,并在您的迁移中参考它)。它看起来像这样:

To get around this, you need to create a custom iterator in your migration (or stick it where it's really useful, and refer to it in your migration). It would look something like this:

def queryset_iterator(queryset, chunksize=1000):
    import gc
    pk = 0
    last_pk = queryset.order_by('-pk')[0].pk
    queryset=queryset.order_by('pk')
    if queryset.count() < 1
        return []
    while pk < last_pk:
        for row in queryset.filter(pk__gt=pk)[:chunksize]:
            pk = row.pk
            yield row
        gc.collect()

然后您的迁移将更改为如下所示:

And then your migrations would change to look like this:

class Migration(DataMigration):

    def forwards(self, orm):
        for item in queryset_iterator(orm['myapp.myclass'].objects.all()):
            if not item.uuid:
                item.uuid = uuid.uuid1()
                item.save()

    def backwards(self, orm):
        for item in queryset_iterator(orm['myapp.myclass'].objects.all()):
            if item.uuid:
                item.uuid = None
                item.save()

这篇关于在数据库中已经存在数据库后添加了UUID字段。有没有办法填充现有数据的UUID字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆