question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

New version of factory_boy does not work with a simple RelatedFactory case

See original GitHub issue

Hi all, I upgraded to factory_boy 2.9.1 and a bunch of my tests are failing. I’ve isolated it down to a simple set of models. This was modeled on the documentation.

import factory

from django.db import models
from django.contrib.auth.models import User

from base.models import Account, Profile


class UserFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = User

    # We pass in 'user' to link the generated Profile to our just-generated
    # User. This will call ProfileFactory(user=our_new_user), thus
    # skipping the SubFactory.
    profile = factory.RelatedFactory(
        'base.tests.factories.broken_factories.ProfileFactory', 'user')
    username = factory.Sequence(lambda n: 'user.username%d' % n)


class AccountFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Account

    admin = factory.SubFactory(UserFactory)
    name = factory.SelfAttribute('admin.email')


class ProfileFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Profile

    # We pass in None to prevent UserFactory from creating another
    # profile (this disables the RelatedFactory)
    user = factory.SubFactory(UserFactory, profile=None)

In my base.models, Account and Profile look like this, roughly:

class Account(models.Model):
    admin = models.ForeignKey(User, related_name='account_admin')
    name = models.CharField(max_length=64)


class Profile(models.Model):
    user = models.OneToOneField(User)

This fails in my tests when I instantiate AccountFactory() with no arguments. This is the error traceback and messaging:

DEBUG 2017-08-03 18:03:29,012 [factory.generate] [declarations.py::generate:392 ] SubFactory: Instantiating base.tests.factories.broken_factories.UserFactory(), create=<factory.builder.BuildStep object at 0x7faf4ef4bf50>
DEBUG 2017-08-03 18:03:29,012 [factory.generate] [declarations.py::evaluate:206 ] Sequence: Computing next value of <function <lambda> at 0x7faf54f447d0> for seq=0
DEBUG 2017-08-03 18:03:29,015 [factory.generate] [declarations.py::call:615 ] RelatedFactory: Generating base.tests.factories.broken_factories.ProfileFactory(<factory.builder.BuildStep object at 0x7faf4f9e3110>, user=<User: user.username0>)
DEBUG 2017-08-03 18:03:29,015 [factory.generate] [declarations.py::evaluate:58 ] LazyFunction: Evaluating <built-in function time> on <factory.builder.BuildStep object at 0x7faf4f76b410>
E
======================================================================
ERROR: test_broken_factory (base.tests.test_factories.FactoryTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/app/djapp/base/tests/test_factories.py", line 51, in test_broken_factory
    AccountFactory()
  File "/usr/local/lib/python2.7/site-packages/factory/base.py", line 46, in __call__
    return cls.create(**kwargs)
  File "/usr/local/lib/python2.7/site-packages/factory/base.py", line 568, in create
    return cls._generate(enums.CREATE_STRATEGY, kwargs)
  File "/usr/local/lib/python2.7/site-packages/factory/base.py", line 505, in _generate
    return step.build()
  File "/usr/local/lib/python2.7/site-packages/factory/builder.py", line 272, in build
    step.resolve(pre)
  File "/usr/local/lib/python2.7/site-packages/factory/builder.py", line 221, in resolve
    self.attributes[field_name] = getattr(self.stub, field_name)
  File "/usr/local/lib/python2.7/site-packages/factory/builder.py", line 363, in __getattr__
    extra=declaration.context,
  File "/usr/local/lib/python2.7/site-packages/factory/declarations.py", line 306, in evaluate
    return self.generate(step, defaults)
  File "/usr/local/lib/python2.7/site-packages/factory/declarations.py", line 395, in generate
    return step.recurse(subfactory, params, force_sequence=force_sequence)
  File "/usr/local/lib/python2.7/site-packages/factory/builder.py", line 233, in recurse
    return builder.build(parent_step=self, force_sequence=force_sequence)
  File "/usr/local/lib/python2.7/site-packages/factory/builder.py", line 293, in build
    context=postgen_context,
  File "/usr/local/lib/python2.7/site-packages/factory/declarations.py", line 617, in call
    return step.recurse(factory, passed_kwargs)
  File "/usr/local/lib/python2.7/site-packages/factory/builder.py", line 233, in recurse
    return builder.build(parent_step=self, force_sequence=force_sequence)
  File "/usr/local/lib/python2.7/site-packages/factory/builder.py", line 279, in build
    kwargs=kwargs,
  File "/usr/local/lib/python2.7/site-packages/factory/base.py", line 314, in instantiate
    return self.factory._create(model, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/factory/django.py", line 165, in _create
    return manager.create(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 394, in create
    obj.save(force_insert=True, using=self.db)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/base.py", line 807, in save
    force_update=force_update, update_fields=update_fields)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/base.py", line 837, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/base.py", line 923, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/base.py", line 962, in _do_insert
    using=using, raw=raw)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 1076, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1107, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 101, in execute
    return self.cursor.execute(query, args)
  File "/usr/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 174, in execute
    self.errorhandler(self, exc, value)
  File "/usr/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
IntegrityError: (1062, "Duplicate entry '1' for key 'user_id'")

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
domino14commented, Aug 4, 2017

2.8.1 worked, and 2.9/2.9.1 don’t work with my code.

0reactions
rbarroiscommented, Jan 28, 2018

I’m closing this issue for now, since it seems to be due to an internals refactor messing up with an private-yet-slightly-documented method.

Please reopen it if the bug is still out there, or if the documentation fixes aren’t sufficient!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Common recipes — Factory Boy stable documentation
Simple Many-to-many relationship . Building the adequate link between two models depends heavily on the use case; factory_boy doesn't provide a “all...
Read more >
Django, Factory boy - can't create subfactory - Stack Overflow
I have solved the problem to create a label first you need to create a profile profile = ProfileFactory.create().
Read more >
pytest-factoryboy - Python Package Health Analysis - Snyk
Latest version published 5 months ago. License: MIT ... No known security issues. popularity ... Looks like pytest-factoryboy is missing a security policy....
Read more >
Factory Boy Documentation - Read the Docs
Factory Boy Documentation, Release 1.3.0 ... handles such cases: it should receive a function taking the ... Simple build, do nothing.
Read more >
Testing Models with Django using Faker and Factory Boy
The factory_boy library(modeled after Factory Girl in Rails) the generation of data for tests. In Django, data for tests was called fixtures, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found