PostgresSQL functions as default value?

Hi there,

I’m trying to use UUID on my Django application, as I prefer to share a UUID instead of a simple ID, this way I have external/internal identificators.

I want Django to tell postgres to set a default value to ‘uuid_generate_v4()’

But it’s not obeying my.

I tried to create a callable with this:

def uuid_generate_v4():
"""
Generates a random UUID based on postgresql native function.

:return: Returns a native UUID.
:rtype: UUID
"""
with connection.cursor() as cursor:
    cursor.execute("SELECT uuid_generate_v4()")
    row = cursor.fetchone()
return row

I also tried this:

class uuid_generate_v4(models.Func):
  template = 'uuid_generate_v4()'
  output_field = models.UUIDField()

But none of it seems to work, is there any way to have a default UUID4 using the uuid-ossp instead of pgcrypto?

As this is more of a PostgreSQL issue than a Django issue, you’ll probably get better answers elsewhere.

But, from what I can quickly find in the PostgreSQL 12 documentation, they have this note:

Note

If you only need randomly-generated (version 4) UUIDs, consider using the gen_random_uuid() function from the pgcrypto module instead.

It looks like the module providing this function, uuid-ossp, isn’t built-in by default - you might need to compile from source.

EDIT: Ok, the above is wrong. As of PostgreSQL 12, the extension is still being provided, it just needs to be installed as an extension in your database:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

This allows the following (from the Django shell_plus):

In [21]: c = connection.cursor()                                                                    
In [22]: c.execute("select uuid_generate_v4()")                                                     
In [23]: print(c.fetchone())                                                                        
(UUID('28be7f6c-fe9e-4095-b253-1d071c03ddb9'),)

Edit #2: While looking for something else, I ran across this: https://docs.djangoproject.com/en/3.0/ref/contrib/postgres/functions/#randomuuid

Ken

I’m not exactly sure what your use case is so this may not apply, but when I want to include default UUIDs for my models, I apply it to the model field itself.

import uuid

from django.db import models


class MyModel(models.Model):
     uuid = models.UUIDField(default=uuid.uuid4, db_index=True)

I’ve been on projects where an abstract model with a UUIDField is used as the superclass for models where we want UUIDs. UUIDs are handled at the Python level, but it has worked for me in practice.

Thanks to both of you.

We were trying to use the select uuid_generate_v4 directly in the ‘default’ field, awaiting that this get’s reflected as a default value in the database, but instead of it, it looks like it just provide this value to the object instead. We wanted to be in database level instead of python level, to make sure the UUID value is not repeated and also save time when the dba is touching the database in raw…

But thinking now, I thing thats a bit fetichist and we can go just with uuid.uuid4 or the option of RandomUUID that comes in django.contrib.