Skip to content

Instantly share code, notes, and snippets.

@rochacbruno
Created February 11, 2012 07:52
Show Gist options
  • Save rochacbruno/1797605 to your computer and use it in GitHub Desktop.
Save rochacbruno/1797605 to your computer and use it in GitHub Desktop.
define_table lazy loaded using class in modules, much more performant then putting in models folder
# modules/tables.py
from gluon.dal import Field
from gluon.validators import *
from gluon.storage import Storage
class Tables(object):
"""Tables stores all dal tables as properties. The properties are lazy loaded so the define_table isn't
Called unless the table is explicitly needed. This also avoids the need to define tables in
a particular order."""
def __init__(self, db, auth, request):
super(Tables, self).__init__()
self._db = db
self._auth = auth
self._request = request
self._tables = Storage()
def __call__(self):
return self._db
def db():
doc = "Convenient way of accessing DAL object"
def fget(self):
return self._db
return locals()
db = property(**db())
def todo():
doc = "Todo table as lazy loaded property"
table_name = 'todo'
def fget(self):
if name not in self._tables:
self._db.define_table(table_name,
Field('name', 'string', length = 50),
Field('created_by', self._db.auth_user, default = self._auth.user_id),
Field('created_on', 'datetime', default = self._request.now)
)
self._db.todo.name.requires = IS_NOT_EMPTY(error_message = 'name is required!')
self._tables[table_name] = self._db.todo
return self._tables[table_name]
return locals()
todo = property(**todo())
def todo_item():
doc = "The todo_item as lazy loaded property"
table_name = 'todo_item'
def fget(self):
if 'todo_item' not in self._tables:
self._db.define_table(table_name,
Field('name', 'string', length = 50),
Field('todo', self.todo),
Field('created_by', self._db.auth_user, default = self._auth.user_id),
Field('created_on', 'datetime', default = self._request.now)
)
self._db.todo_item.name.requires = IS_NOT_EMPTY(error_message = 'Item is required!')
self._tables[table_name] = self._db.todo_item
return self._tables[table_name]
return locals()
todo_item = property(**todo_item())
# models/db.py
dbdal = DAL('sqlite://storage.sqlite')
response.generic_patterns = ['*'] if request.is_local else []
from gluon.tools import Auth, Crud, Service, PluginManager, prettydate
auth = Auth(dbdal, hmac_key=Auth.get_or_create_key())
crud, service, plugins = Crud(dbdal), Service(), PluginManager()
auth.define_tables()
mail=auth.settings.mailer
mail.settings.server = 'logging' or 'smtp.gmail.com:587'
mail.settings.sender = '[email protected]'
mail.settings.login = 'username:password'
auth.settings.registration_requires_verification = False
auth.settings.registration_requires_approval = False
auth.settings.reset_password_requires_verification = True
from gluon.contrib.login_methods.rpx_account import use_janrain
use_janrain(auth,filename='private/janrain.key')
import tables
# name class db so I can access with same syntax as normal
db = tables.Tables(dbdal, auth, request)
# controllers/todo.py
def index():
# normally you would do db(db.todo.id>0).select(), since I assigned db = Tables()
# so I am accessing dal as property db of Tables instance
todos = db.db(db.todo.id>0).select()
fields = ['name']
form = SQLFORM(db.todo, fields = fields)
if form.process(onsuccess = None, onfailure = None).accepted:
redirect(URL('todo','todo', args = (form.vars.id)))
return dict(form = form, todos = todos)
def todo():
todo = db.todo(request.args(0) or redirect(URL('todo','index')))
todo_items = db.db(db.todo_item.todo == todo.id).select(cache=(cache.ram, 60))
fields = ['name']
db.todo_item.todo.default = todo.id
form = SQLFORM(db.todo_item, fields = fields)
if form.process(onsuccess = None, onfailure = None).accepted:
cache.ram.clear()
redirect(URL('todo','todo', args = (request.args(0))))
return dict(todo = todo, todo_items = todo_items, form = form)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment