UUIDField
用作主键时,它不会为您生成UUID,您需要在保存对象之前自己生成。可能自从我上次使用UUIDField
以来有所改变,但是在我最后使用UUIDField
时,您必须自己指定UUID值(例如,当您创建对象时,Django不允许您保存具有空UUID的对象并生成一个)。查看Django文档示例加强了我的想法,因为它们提供了一个default=uuid.uuid4()
,例如在主键中。class MyUUIDModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
^
|__ calls uuid.uuid4()
要比较不同UUID版本的属性,请参见此问题:Which UUID version to use?
对于许多应用程序而言,UUID4就足够了
如果您只想生成UUID并继续进行生活,像上面示例中的uuid.uuid4()
一样就行了。UUID4是随机UUID,发生冲突的可能性非常小,尤其是如果您每秒钟不会生成大量UUID。
最后,假设在Python或Django中直接使用
uuid_generate_v1mc
不可用,鉴于博客文章指出的碎片化问题,是否有方法强制使用它?
一个带有随机MAC地址的Python UUID1,例如uuid-ossp
的uuid_generate_v1mc
您链接的博客提到了使用UUID1。 Python的uuid.uuid1()
接受一个参数,该参数用于替代默认的真实硬件MAC地址(48位)。因为这些随机位是UUID1的结尾,所以UUID1的前几位可以是顺序/基于时间戳的,以限制索引的碎片化。
因此,
uuid.uuid1(random_48_bits)
应该可以得到与uuid_generate_v1mc
相似的结果,它是带有随机MAC地址的UUID1。
为了生成一个随机的48位数,我们可以使用以下虚拟示例:
import random
random_48_bits = random.randint(0, 2**48 - 1)
试一试:
>>> import uuid
>>> import random
>>> 2 ** 48 - 1
281474976710655
>>> uuid.uuid1(random.randint(0, 281474976710655))
UUID('c5ecbde1-cbf4-11e5-a759-6096cb89d9a5')
现在将其制作成函数,并将其用作Django UUIDField
的default
。
自定义UUID以及Instagram的示例
请注意,完全可以想出自己的自定义UUID方案,并使用可用位来编码对应用程序有用的信息。
例如,您可以使用一些位来编码给定用户的国家/地区,一些位来存储时间戳,一些随机位等。
您可能需要阅读Instagram(建立在Django和PostgreSQL上)如何构建自己的UUID方案以帮助分片的文章。
from django.db.models import Func, UUIDField
class RandomUUID(Func):
template = "uuid_in(md5(random()::text || clock_timestamp()::text)::cstring)"
output_field = UUIDField()
def add_guid(apps, schema_editor):
MyModel= apps.get_model("app", "MyModel")
MyModel.objects.update(guid=lib_models.RandomUUID())
class Migration(migrations.Migration):
...
operations = [
migrations.RunPython(add_guid, reverse_code=migrations.RunPython.noop),
]
uuid_generate_v1mc
一样,以限制索引碎片化。 - bakkal