How to create factory column for self referential column in a model in pytest?

471 Views Asked by At

I have a model with a column which is a self referential foreign key.

class Foo(db.Model):
     foo_ref_id = db.Column(
        db.Integer,
        db.ForeignKey("foo.id", ondelete="CASCADE"),
        nullable=True,
        index=True,
      )

I am trying to create a factory model for the same model:

class FooFactory(factory.alchemy.SQLAlchemyModelFactory):
    class Meta:
        model = Foo

    context_base_id = factory.SubFactory("tests.factories.BaseFactory", parent=None)
    context_base_id = factory.LazyAttribute(lambda x: BaseFactory(parent=None))
    context_base_id = factory.Trait(
          parent_category=factory.SubFactory("tests.factories.BaseFactory")
    )

I have tried the 3 ways of doing achieving this. All of them return an error of maximum depth of recursion exceeded.

What is the proper way of doing this?

1

There are 1 best solutions below

1
On BEST ANSWER

You have to tell the factory where to stop.

The simplest option is to pass an extra parameter to the SubFactory call:

class FooFactory(factory.alchemy.SQLAlchemyModelFactory):
    class Meta:
        model = Foo
    parent = factory.SubFactory(
        'apps.foo.factories.FooFactory',
        parent__parent__parent=None,
    )
    # Other fields here

With the code above:

  1. The first FooFactory will set self.parent = FooFactory(parent__parent__parent=None)
  2. The parent will set self.parent = FooFactory(parent__parent=None)
  3. The grandparent will set self.parent = FooFactory(parent=None)
  4. The great-grandparent will set self.parent = None, thus ending the recursion.