0

In factory boy it is possible to create a sqlalchemy object with a relationship to another table. There is a common recipe for Choosing from a populated table which is made for django, and I want to do this now for flask.

So I'd think that I have use this line.

user = factory.Iterator(User.query.all())

But of course it doesn't work. I get an error that there is no application context. It states in the documentation that the query wont be evaluated until the first call to to the Userfactory, however the error occurs when importing.

I want to have a factory that chooses the foreign key from an object that I already created. How can I do this in flask?

Harm
  • 109
  • 9

1 Answers1

1

The example works for Django because a QuerySet is lazy; i.e. the request only hits the database when trying to iterate on it. FactoryBoy's Iterator will only start iterating on the provided generator when the first factory call is made.

For SQLAlchemy, you need a way to return a generator instead of a list; I think this would work with factory.Iterator(User.query). User.query.all() explicitly sends the SQL request and retrieves the results, which will fail before the app is properly configured.

If that doesn't work (the SQLAlchemy docs aren't very clear on the Query iteration behaviour), you could try with a helper function:

def lazy_users():
  """Turn `User.query.all()` into a lazily evaluated generator"""
  yield from User.query.all()

class ProfileFactory(...):
  user = factory.Iterator(lazy_users())
Xelnor
  • 3,194
  • 12
  • 14
  • Thank you very much for your help. It doesn't work with User.query, but the lazy_users helper function does work. I had to change it to: `while True: yield choice(User.query.all())`. Because then it continues to generate users in cases where there are more profiles than users. – Harm Oct 18 '21 at 20:32