August 14, 2009

Django Model Trick: UUIDs

One of the most important model tricks we used in our application was UUIDs. We were stuck on python 2.4 so we had to copy the UUID code in from later pythons, but now you can have it with even less work.

Django gives you automatically incrementing integer IDs for everything, which is possibly the worst ID scheme known to man. The only thing that recommends it is that integers are very small. But since everyone starts at the same place, they're only unique for one spin of the database... and that's not good enough.

In our configuration application model ID fields were something like:

uuid = models.CharField(max_length=36, primary_key=True,
default=make_uuid, editable=False)

where make_uuid is:

def make_uuid():
return str(uuid.uuid4())

What does this give you for your jumbo-size keys? Freedom to toss objects around like confetti!

If I make a test fixture, and my coworker makes a test fixture, and we want to load them on the same machine to run a joint test? There are no ID conflicts.

If I make a useful data setup and want to export it and give it to someone else, it will not overwrite the partial setup she already has.

You can also give me an object A, then later modify it to A' and send me that exported object... and when I import it, you know it will overwrite A because that's the ID that matches.

There are also some other nice features of UUID keys, for example: if I get the object ID for a foo when I wanted a bar, it won't resolve to a foo by coincidence because the foo and bar ID spaces are not going to overlap.

UUIDs - because your object IS a special snowflake.

1 comment:

  1. From Todd Rowell (another one of the coders on the project I'm discussing) via email:

    "We're using UUIDs, too, for some of the same things as the configuration project but they also make nice usernames when your site identifies users by email address and you still want to use the Django auth code. We compress them to 22 chars which is nice when you want to keep things short."

    ReplyDelete