How do Django and / or Python generate UUIDs in Postgresql?
But there are many kinds of UUIDs, and itβs completely unclear to me which one is generated in Django
When you use a UUIDField as the primary key in Django, it does not generate a UUID for you, you generate it yourself before saving the object
I donβt know if things have changed since then, but the last time I used UUIDField , you had to specify the UUID value yourself (for example, when you create an object, Django will not allow you to save the object with an empty UUID and create a database) . Looking at the Django documentation samples, I reinforce my point because they provide default=uuid.uuid4() , for example. in the primary key.
class MyUUIDModel(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) ^ |__ calls uuid.uuid4()
Which version of UUID to choose
To compare the properties of different versions of UUIDs, see the following question: Which version of UUID should I use?
UUID4 is great for many applications.
If you just want to generate a UUID and continue your life, uuid.uuid4() , as in the above snippet, is just fine. UUID4 is a random UUID, and the chance of a collision is so small that you have nothing to worry about, especially if you don't generate them a ton per second.
Finally, given the fragmentation issue uuid_generate_v1mc in the blog post and the assumption that uuid_generate_v1mc not directly available in Python or Django, is there a way to get them to use it?
Python UUID1 with random MAC address e.g. uuid-ossp uuid_generate_v1mc
The blog you are referencing mentions the use of UUID1. Python uuid.uuid1() accepts a parameter that is used instead of the default real hardware MAC address (48 bits). Since these random bits are the end of UUID1, the first bits of UUID1 can be sequential / time-based to limit index fragmentation.
So,
uuid.uuid1(random_48_bits)
You should get results similar to uuid_generate_v1mc , which is UUID1 with a random MAC address.
To generate random 48 bits as a dummy example, we can use:
import random random_48_bits = random.randint(0, 2**48 - 1)
Try:
>>> import uuid >>> import random >>> 2 ** 48 - 1 281474976710655 >>> uuid.uuid1(random.randint(0, 281474976710655)) UUID('c5ecbde1-cbf4-11e5-a759-6096cb89d9a5')
Now make a function out of it and use it as default for your Django UUIDField
Custom UUIDs and Instagram example
Note that itβs perfectly normal to come up with your own custom UUID scheme and use the available bits to encode information that may be useful for your application.
For instance. You can use several bits to encode the country of a given user, several bits with a time stamp, some bits for randomness, etc.
You might want to read how Instagram (built on Django and PostgreSQL) developed its own UUID scheme to help break up .