-
Notifications
You must be signed in to change notification settings - Fork 401
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Option to make Faker return unique values #305
Comments
Running into this very same issue too. |
This looks interesting. However, See also:
|
Wrapping I'm leery of us adding much code here, as there's a lot of permutations of this behavior, depending on which Personally, I think this might be a case where the best solution is to call
I'm going to go ahead and close this, @rbarrois if you feel differently feel free to reopen. |
fyi it appears that similar libraries such as PHP Faker or the Ruby version have options to guarantee uniqueness - see discussion at e.g. faker-ruby/faker#251 (came here because I'm new to the library and recently read https://kev.inburke.com/kevin/faker-js-problems/)
I suppose one of the trade-offs in this would be to give up using real dictionary words or throwing an error if you've used up the whole dictionary |
Has anyone managed to work around this yet? I've tried using a sequence, but that doesn't work:
|
|
@danihodovic you can use name = factory.Sequence(lambda n: factory.Faker("company").generate() + f" {n}") |
Is there a way to use Faker's unique API in factory boy? ie from faker import Faker
fake = Faker()
names = [fake.unique.first_name() for i in range(500)] # All unique |
@arthurHamon2 is making good progress in #820. |
Oh, that's (the OP) almost what I did: # app/tests/__init__.py
class UniqueFaker(factory.Faker):
# based on factory.faker.Faker.generate
def generate(self, params):
locale = params.pop('locale')
subfaker = self._get_faker(locale)
return subfaker.unique.format(self.provider, **params)
class MyTestCase(TestCase):
def tearDown(self):
for l, v in factory.Faker._FAKER_REGISTRY.items():
factory.Faker._get_faker(locale=l).unique.clear()
# app/tests/factories.py
class ProductFactory(factory.django.DjangoModelFactory):
...
size = t.UniqueFaker('size') # S, M, L, ... The idea is to override the method that calls the
Non-performant? Meaning, slow? There seems to be nothing that suggests that. I'd say subclassing is the best workaround I could find. Not that it means
Sounds like a different use case. I wonder if one'd want to reproduce test failures for such tests...
AFAICS, nobody's suggesting enforcing uniqueness globally. Usually that's needed for database fields with a unique constraint.
Doesn't work since |
Apparently it was only renamed to import factory
from faker import Faker
from faker.proxy import UniqueProxy
class UniqueFaker(factory.Faker):
def evaluate(self, instance, step, extra):
locale = extra.pop('locale')
subfaker: Faker = self._get_faker(locale)
unique_proxy: UniqueProxy = subfaker.unique
return unique_proxy.format(self.provider, **extra) |
Isn't it possible to enable a |
I see random test failures because e.g.
factory.Faker('company')
returns duplicate values (usually after a few hundred calls, but as low as the second call). To remedy this, I wrote a subclass ofFaker
that keeps track of values returned so it can ensure uniqueness. The code is fairly trivial:Is there any interest in either adding this subclass to factoryboy, or integrating the functionality into
Faker
itself?The text was updated successfully, but these errors were encountered: