Significant design change: commit data after some requests to avoid multiple database hits when using SQLALchemy

This commit is contained in:
Matt Wright
2012-08-17 13:19:40 -04:00
parent b7d71f8c59
commit a39f46854e
5 changed files with 21 additions and 4 deletions
+2
View File
@@ -24,6 +24,7 @@ from flask.ext.security.exceptions import RoleNotFoundError
def create_roles():
for role in ('admin', 'editor', 'author'):
current_app.security.datastore.create_role(name=role)
current_app.security.datastore._commit()
def create_users():
@@ -34,6 +35,7 @@ def create_users():
('tiya@lp.com', 'password', [], False)):
current_app.security.datastore.create_user(
email=u[0], password=u[1], roles=u[2], active=u[3])
current_app.security.datastore._commit()
def populate_data():
+5 -2
View File
@@ -33,6 +33,9 @@ class UserDatastore(object):
self.user_model = user_model
self.role_model = role_model
def _commit(self, *args, **kwargs):
pass
def _save_model(self, model, **kwargs):
raise NotImplementedError(
"User datastore does not implement _save_model method")
@@ -218,15 +221,15 @@ class SQLAlchemyUserDatastore(UserDatastore):
Security(app, SQLAlchemyUserDatastore(db, User, Role))
"""
def _commit(self, *args, **kwargs):
self.db.session.commit()
def _save_model(self, model):
self.db.session.add(model)
self.db.session.commit()
return model
def _delete_model(self, model):
self.db.session.delete(model)
self.db.session.commit()
def _do_find_user(self, **kwargs):
return self.user_model.query.filter_by(**kwargs).first()
+12 -1
View File
@@ -10,7 +10,7 @@
"""
from flask import current_app as app, redirect, request, \
render_template, jsonify, Blueprint
render_template, jsonify, after_this_request, Blueprint
from werkzeug.datastructures import MultiDict
from werkzeug.local import LocalProxy
@@ -64,12 +64,19 @@ def _json_auth_error(msg):
return resp
def _commit_data(response=None):
_datastore._commit()
return response
def authenticate():
"""View function which handles an authentication request."""
confirm_url = None
form_data = MultiDict(request.json) if request.json else request.form
form = LoginForm(form_data)
after_this_request(_commit_data)
try:
user = _security.auth_provider.authenticate(form)
@@ -130,6 +137,9 @@ def register():
# Create user
u = _datastore.create_user(**form.to_dict())
# Save the user so the ID is created
_commit_data()
# Send confirmation instructions if necessary
t = reset_confirmation_token(u) if _security.confirmable else None
@@ -212,6 +222,7 @@ def send_confirmation():
def confirm_email(token):
"""View function which handles a email confirmation request."""
after_this_request(_commit_data)
try:
user = confirm_by_token(token)
+1 -1
View File
@@ -34,7 +34,7 @@ setup(
include_package_data=True,
platforms='any',
install_requires=[
'Flask>=0.8',
'Flask>=0.9',
'Flask-Login>=0.1.3',
'Flask-Principal>=0.3',
'Flask-WTF>=0.5.4',
+1
View File
@@ -182,6 +182,7 @@ class DefaultSecurityTests(SecurityTest):
with self.app.test_request_context('/'):
user = self.app.security.datastore.find_user(email='matt@lp.com')
self.app.security.datastore.delete_user(user)
self.app.security.datastore._commit()
r = self._get('/')
self.assertNotIn('Hello matt@lp.com', r.data)