Re: [flask] Best way to use SQLAlchemy
- From:
- Giovanni Giorgi
- Date:
- 2011-07-06 @ 12:10
Hi,
htank you for youtr hanswer, but I have some problem using the
init_app function of SQLAlchemy.
Here is the testcase, form a python prompt:
>>> app.config['SQLALCHEMY_DATABASE_URI']
'sqlite:///../devdb-sqlalchemy.sqlite3'
>>> db=SQLAlchemy()
>>> db
<SQLAlchemy engine=None>
>>> db.init_app(app)
>>> db
<SQLAlchemy engine=None>
>>> db2=SQLAlchemy(app)
>>> db2
<SQLAlchemy engine='sqlite:///../devdb-sqlalchemy.sqlite3'>
>>>
It seems the db variable is not properly
initialized if I do not pass 'app' to the SQLAlchemy constructor.
When I try to invoke db.create_all() I get
RuntimeError: application not registered on db instance and no
application bound to current context
db2 instance works great, instead.
Where am I wrong?
Thanks
On Wed, July 6, 2011 11:14 am, Armin Ronacher wrote:
> Hi,
>
> On 7/6/11 11:10 AM, Giovanni Giorgi wrote:
>> I'd like instead using something like the one used by flaskr, because of
>> unit testing:
>>
>> def connect_db():
>> """Returns a new connection to the database."""
>> return SQLAlchemy(app)
>>
>> connect_db is called every time it is needed (for example inside a
>> @app.before_request handler).
>>
>> Is this a good idea, or it will force to regenerate the SQLAlchemy
>> strutures every time, leading to a slow/bad approach?
> That's generally not a good idea, but you can do something similar with
> how SQLAlchemy works. You create the application on the fly as you need
> it an later initialize SQLAlchemy with it:
>
> db = SQLAlchemy()
>
> def create_app(config):
> app = Flask(__name__)
> app.config.update(config)
> register_views(app)
> db.init_app(app)
> return app
>
> It's better to also couple that with blueprints, then you don't have to
> create the views in a function:
>
> db = SQLAlchemy()
> frontend = Blueprint('frontend', __name__)
>
> @frontend.route('/')
> def index():
> ...
>
> def create_app(config):
> app = Flask(__name__)
> app.config.update(config)
> app.register_blueprint(frontend)
> db.init_app(app)
> return app
>
>
> Regards,
> Armin
>
--
Senior Consultant
http://gioorgi.com
Re: [flask] Best way to use SQLAlchemy
- From:
- Armin Ronacher
- Date:
- 2011-07-06 @ 12:37
Hi,
On 2011-07-06 2:10 PM, Giovanni Giorgi wrote:
> It seems the db variable is not properly
> initialized if I do not pass 'app' to the SQLAlchemy constructor.
It is, but it is initialized only when it's bound to an application.
> When I try to invoke db.create_all() I get
> RuntimeError: application not registered on db instance and no
> application bound to current context
You will need to do this:
app = create_application()
with app.test_request_context():
db.create_all()
Why? Because the with statement binds the test-request context to the
current thread and this way the SQLAlchemy extensions can figure out the
current settings. Alternatively you can also do db.create_all(app=app)
I think.
Regards,
Armin
Re: [flask] Best way to use SQLAlchemy
- From:
- Giovanni Giorgi
- Date:
- 2011-07-06 @ 15:48
Thank you,
I have fixed the init db, but I am unable to do tests.
First of all, I was unable to find register_views on Flask package,
so it is missed on my create_app() function.
I ended up with something like:
def setUp(self):
"""Before each test, set up a blank database"""
wpWebPublisher.app.config['SQLALCHEMY_DATABASE_URI']="sqlite:///:memory:"
wpWebPublisher.app.config['TESTING'] = True
# Update my config....
wpWebPublisher.app=wpWebPublisher.create_app(wpWebPublisher.app.config)
self.app = wpWebPublisher.app.test_client()
wpWebPublisher.init_db()
It seems ok, but when I try to run simple test like
self.app.get('/about',follow_redirects=True)
I get a 404 error... I need to create a test request also?
Why flaskr_test.py needn't it? :)
On Wed, July 6, 2011 2:37 pm, Armin Ronacher wrote:
> Hi,
>
> On 2011-07-06 2:10 PM, Giovanni Giorgi wrote:
>> It seems the db variable is not properly
>> initialized if I do not pass 'app' to the SQLAlchemy constructor.
> It is, but it is initialized only when it's bound to an application.
>
>> When I try to invoke db.create_all() I get
>> RuntimeError: application not registered on db instance and no
>> application bound to current context
> You will need to do this:
>
> app = create_application()
> with app.test_request_context():
> db.create_all()
>
> Why? Because the with statement binds the test-request context to the
> current thread and this way the SQLAlchemy extensions can figure out the
> current settings. Alternatively you can also do db.create_all(app=app)
> I think.
>
>
> Regards,
> Armin
>
--
Senior Consultant
http://gioorgi.com