On Thursday, August 23, 2012 3:01:50 AM UTC+1, Michael Bayer wrote:
>
>
> On Aug 22, 2012, at 5:33 PM, David McKeone wrote: 
>
> > I suppose I should be more clear.  This is really a long term question, 
> I was just looking for some kind of answer now because I don't want to code 
> myself into a corner in the short term.  Currently I can make requests 
> outside of a flask request context by using the app.test_request_context() 
> context manager, and it seems to do the right thing.   
> > 
> > In the long term I'm looking for 2 (maybe 3) things that I already get 
> from Flask-SQLAlchemy: 
> > 1) Session teardown for every request (looks like that is done with a 
> call to session.remove() in the request teardown) 
>
> you can use the Session provided by flask-sqlalchemy, which has the nice 
> quality that it aligns itself with the current request. 
>
> He can make that feature more open-ended though.   I should be able to say 
> flask_sqlalchemy.request_scope(some_sessionmaker) to set that up with any 
> sessionmaker of my choosing. 
>
>
> > 2) Debug query tracking for use with Flask-DebugToolbar  (Plus 
> compatibility with other plug-ins that may expect Flask-SQLAlchemy) 
>
> the logic i see in flask-sqlalchemy related to debug tracking has no 
> connection to the "db.Model" class at all.   its just some connection 
> events which are ultimately established via the "SQLAlchemy" class.  Your 
> existing non-flask SQLA models will participate in the Session/Engine used 
> by Flask without impacting this functionaltiy. 
>
>
> > 3) The Model.query behaviour (it's nice, but I could live without it, 
> since its really just syntactic) 
>
> scoped_session has a query_property available, so you can pull that from 
> Flask's scoped_session using SQLAlchemy public APIs like this: 
>
> sa = SQLAlchemy(db) 
>
> # API: 
> http://docs.sqlalchemy.org/en/rel_0_7/orm/session.html#sqlalchemy.orm.scoping.ScopedSession.query_property
>  
> Base.query = sa.session.query_property 
>
>
> or to get exactly flask's, which appears to add three methods get_or_404, 
> first_or_404, paginate: 
>
> Base.query = flask_sqlalchemy._QueryProperty(sa) 
>
> > 
> > 
> > Didn't say this explicitly; for now I will do what you say and forge 
> ahead with things.  I think I see the path, but I'll make sure to let you 
> (the list) know if I run into trouble. 
>
> good luck ! 
>


Slugged it out today and got this working, hooray!  Thanks again for your 
help Mike (and for the time you probably put in to parse the 
Flask-SQLAlchemy code).  If you are at PyCon this year I WILL find you and 
I WILL buy you beer, unless you don't drink, in which case I WILL buy you 
soda or coffee.

I haven't done the Base.query part, and I may never do it (more below), but 
everything else works great and all my tests pass after switching to the 
new method.

The more I use the new system the more I wish I would have started with it. 
 Perhaps I can get it documented as an option, because I find it makes it 
far more clear where the models belong in the grand scheme of things.  Now, 
not everyone has 93 tables, a boat-load of relationships and requirements 
for doing things outside of HTTP like I do, so I can understand why it's 
been done the way that it's been done, but having to pass the db instance 
into all of my model definitions (and the resulting project structure 
issues I had) just wasn't worth it.  I've also found that having to use the 
session directly makes it far more clear which session is being used, and 
how.  Not to mention the benefits from being able to decouple my models 
from Flask completely.

So, in the name of Google search completeness,  here is the solution that I 
ultimately ended up with, adapted for the simple User model from above, for 
those like me who want/need it.  (It's quite simple, and I'm amazed that it 
hadn't occurred to me to try it like this)

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

app =  Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True)
    email = Column(String(120), unique=True)

    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

    def __repr__(self):
        return '<User %r>' % (self.name)

@app.before_first_request
def setup():
    # Recreate database each time for demo
    Base.metadata.drop_all(bind=db.engine)
    Base.metadata.create_all(bind=db.engine)
    db.session.add(User('Bob Jones', 'b...@gmail.com'))
    db.session.add(User('Joe Quimby', 'e...@joes.com'))
    db.session.commit()

@app.route('/')
def root():
    users = db.session.query(User).all()
    return u"<br>".join([u"{0}: {1}".format(user.name, user.email) for user 
in users])

if __name__ == '__main__':
    app.run('127.0.0.1', 5000)


 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/3nDcblYbMQYJ.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to