Home > Software design >  Generating new unique uuid4 in Django for each object of Factory class
Generating new unique uuid4 in Django for each object of Factory class

Time:02-13

I have a Model Sector which has a id field (pk) which is UUID4 type. I am trying to populate that table(Sector Model) using faker and factory_boy.

But,

DETAIL:  Key (id)=(46f0cf58-7e63-4d0b-9dff-e157261562d2) already exists.

This is the error I am getting.

Is it possible that the error is due to the fact that everytime I am creating SectorFactory objects (which is in a different django app) and the seed gets reset to some previous number causing the uuid to repeat?

Please suggest some ways as to how I shall get unique uuid for each Factory object?

SectorFactory class

import uuid
from factory.django import DjangoModelFactory
from factory.faker import Faker
from factory import Sequence


class SectorFactory(DjangoModelFactory): 
    id = uuid.uuid4()
    name = Sequence(lambda n: f'Sector-{n}')

    class Meta:
        model = 'user.Sector'
        django_get_or_create = ['name']

Class Sector

class Sector(models.Model):
    id      = models.UUIDField(primary_key=True, default = uuid.uuid4, editable=False)
    name    = models.CharField(max_length=100)

    class Meta:
        db_table = 'sector'
        constraints = [
            models.UniqueConstraint('name', name = 'unique_sector_name')
        ]

The script which creates the custom command to create SectorFactory objects.

from types import NoneType
from django.core.management.base import BaseCommand
from user.factories import SectorFactory

class Command(BaseCommand):
    help = 'Generate fake data and seed the models with them.'

    
    def add_arguments(self, parser) -> None:
        parser.add_argument( '--amount', type=int, help='The amount of fake objects to create.' )

    def _generate_sectors(self, amount):
        for _ in range(amount):
            SectorFactory()
    
    def handle(self, *args, **options) :

        amount = options['amount']
        if(type(amount) == NoneType): amount = 10
        
        self._generate_sectors(amount)

CodePudding user response:

just use like this:

class SectorFactory(DjangoModelFactory): 
    id = Faker('uuid4')
    name = Sequence(lambda n: f'Sector-{n}')

    class Meta:
        model = 'user.Sector'
        django_get_or_create = ['name']

CodePudding user response:

Well, the solution was rather pretty trivial and rather quite ignorant of me!

Instead of using uuid module, one must use Faker's uuid4 provider.

But I, still wonder why using uuid module(which is created for the sole purpose of generating uuid(s)) did not work.

  • Related