Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two ways of creating a flask-SQLAlchemy BaseQuery object - only one works, why?

This question is a simplification of "Filter relationships and paginate in Flask-SQLAlchemy", and an answer here would probably yield a solution there too.

Say I have a simple model class Design:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)

class Design(db.Model):
    __tablename__ = 'design'
    id = db.Column(db.Integer, primary_key=True)
    designname = db.Column(db.String(64))

I can get a Flask-SQLAlchemy BaseQuery object like this:

>>> Design.query
<flask_sqlalchemy.BaseQuery object at 0x7f0b29c63990>

And I can get data back as you would expect:

>>> Design.query.all()
[<item1>, <item2>, <item3>]

I can also get a BaseQuery object this way (which I think is necessary for more complex query, e.g., one with joins):

>>> db.Query(Design)
<flask_sqlalchemy.BaseQuery object at 0x7f0b29c6fdd0>

It looks like it should be the same object type - indeed, the SQL generated is identical:

>>> str(db.Query(Design)) ==  str(Design.query)
True

And yet, when I try the all() method here, it doesn't work:

>>> db.Query(Design).all()
Traceback (most recent call last):
File "<debugger>", line 1, in <module>
db.Query(Design).all()
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2320, in all
return list(self)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2437, in __iter__
self.session._autoflush()
AttributeError: 'NoneType' object has no attribute '_autoflush'

EDIT: I believe the problem is that the second approach is not attaching a session to the BaseQuery object. The first method has one:

>>> Design.query.session
<flask_sqlalchemy.SignallingSession object at 0x7f0b29fbd510>

But the other approach does not:

>>> db.Query(Design).session is None
True

Any insight is much appreciated.

like image 275
Owen Avatar asked Sep 20 '25 03:09

Owen


1 Answers

You should be able to use

db.session.query(Design).all()

session.query is how you would perform queries when using SQLAlchemy without Flask-SQLAlchemy.

UPDATE

To perform a join using Flask-SQLAlchemy's BaseQuery:

Design.query.join(YourOtherModel).all()
like image 180
dirn Avatar answered Sep 22 '25 17:09

dirn