Unable to query db inside factory ('Iterator' object has no attribute '_sa_instance_state')
See original GitHub issueI got this factory:
class DepartmentFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = models.Department
sqlalchemy_session = Session
abbreviation = 'MATH'
@factory.lazy_attribute
def school(self):
return factory.Iterator(Session.query(models.School).all())
And I get this error:
AttributeError: 'Iterator' object has no attribute '_sa_instance_state'
I’ve checked and made sure that the query returns a list of School objects.
Issue Analytics
- State:
- Created 6 years ago
- Comments:11 (5 by maintainers)
Top Results From Across the Web
SQLAlchemy AttributeError: 'Query' object has no attribute ...
What I want basically is to create the objects I need to retrieve from the database to complete the data needed for a...
Read more >Using a named iterator in an SQLJ application - IBM Db2 11.1
You declare any result set iterator using an iterator declaration clause. This causes an iterator class to be created that has the same...
Read more >Iterate a Cursor in mongosh — MongoDB Manual
The db.collection.find() method returns a cursor. To access the documents, you need to iterate the cursor. However, in mongosh , if the returned...
Read more >Multi-Row Query Results--SQLJ Iterators
A SQLJ iterator object is an instantiation of such a specifically declared iterator class, with a fixed number of columns of predefined type....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Turning it into a generator function fixed it, thanks for the extensive explanation. Will use that for now. Treating it differently (and wrapping it accordingly) depending on if it’s an SQLAlchemy one or not feels the most natural to me (aka. the user does not have to care), but that is surely your decision to make.
Thanks for the in-depth explanation about the lack of self, the more you know! 😄 It was a bit of an eye-sore both for me and my IDE so solved it this way:
😜
Oh, thanks for the stack!
Indeed, the
factory.Iterator
/factory.iterator
functions work best with a generator function. It should work with:Let’s dive under the hood here: a generator function (anything containing
yield
) returns a special object, which will only execute the function’s code (up to the nextyield
statement) oncenext(x)
is called on it.Django’s querysets are built upon generators, and work natively; however, it seems that SQLAlchemy’s querysets will evaluate directly; using a
yield from x
is equivalent tofor i in x: yield i
, and “wraps” the call in a generator.This could be fixed either through better docs, or in the code; I’ll have to see which way feels most natural.
Regarding the lack of
self
:There is some “dark magic” occurring in factory_boy: basically, the engine will collect all attributes from your class definition, and store them in some internal structures for later use.
I use the
self
parameter to calls because it feels more natural, but that’s actually a trick 😉 When creating an object, a method of those definitions is called with a stub for the attributes of the object to be built. Once that stub is filled, its attributes are used as kwargs for the actual model.Since an iterator cannot be tuned for the object being built (whereas a
lazy_attribute
is designed for that!), there is noself
parameter.