I have developed some applications in web2py, and 2 are running
currently in gae, but now i have serious problem.
My current project is a social application, and when i design
(example) the tables to make an user follow the actions other user
(twitter like) I find that many-to-many relationships in app-engine
are not easily supported.
From my understanding using the tools present in web2py right i would
need to do a lot of processing in memory, an that would hurt
performance greatly.
The pattern proposed by app store developers uses lists and "parent"
relationship:
class Message(db.Model):
sender = db.StringProperty()
body = db.TextProperty()
class MessageIndex(db.Model):
receivers = db.StringListProperty()
indexes = MessageIndex.all(keys_only = True).filter('receivers = ', user_id)
keys = [k.parent() for k in indexes)
messages = db.get(keys)
For using that pattern in web2py I would need a method for specifying
the parent of a model instance. Can I specify that relationship using
any method I don't know? If not, would it be hard to implement?
Thanks in advance!
Thanks again, Carles.
Carles
Currently i'm looking at the code massimo told me about but i think
that the problem isn't here.
I explain: the parent is assigned when the child entity is created (at
the constructor level), to ensure all entities on the same group are
stored together (or close), that way transactions are feasible.
I don't think i'm capable of doing that right now, but my proposed
soultion (just an idea) is to extend the field definition syntax for
reference fields, adding an atribute to indicate this tipe of
relationship.
Example (blatantly stolen from the book):
db.define_table('person',
Field('name'))
db.define_table('dog',
Field('name'),
Field('owner', db.person, relationship="parent"))
On SQL databases that attribute would be ignored, but in GAE web2py
would enforce the parent relationship at creation and dog[id].parent
would return the result of dog_instance.parent()
I don't know if this is feasible or if i'm total crazy (an option to
consider). Opinions?
Carles
I'll try tomorrow.
Thanks a lot, Dave.
Just to organize the things in my head...
Thanks again.
There isn't a deadline, tale your time :)
Carles
You are shedding some light on doing relationships the GAE way.
Thanks again.
I look forward to the next message, this way gae is really appeling.
And your way of teaching is fun, really!.
Moreover, Massimo, can't this method be the default behaviour to
IS_IN_DB when running on gae?
I't seems a good fit. Just my 2 cents.
But i'm drifting, your explanations are great and when you tell us the
last part of the method (putting references on the parent) i'd be glad
to code a working example and send to the list.
Traceback (most recent call last):
File "/Users/lauer/web2py/gluon/restricted.py", line 178, in restricted
exec ccode in environment
File "/Users/lauer/web2py/applications/web2pytodo/controllers/default.py:user",
line 56, in <module>
File "/Users/lauer/web2py/gluon/globals.py", line 96, in <lambda>
self._caller = lambda f: f()
File "/Users/lauer/web2py/applications/web2pytodo/controllers/default.py:user",
line 35, in user
File "/Users/lauer/web2py/gluon/tools.py", line 966, in __call__
return self.login()
File "/Users/lauer/web2py/gluon/tools.py", line 1419, in login
self.log_event(log % self.user)
File "/Users/lauer/web2py/gluon/tools.py", line 1180, in log_event
origin=origin, user_id=user_id)
File "/Users/lauer/web2py/gluon/contrib/gql.py", line 281, in insert
self._last_reference = tmp
File "/Users/lauer/web2py/gluon/sql.py", line 1611, in __setattr__
raise SyntaxError, 'Object exists and cannot be redefined: %s' % key
SyntaxError: Object exists and cannot be redefined: _last_reference
Any thoughts?
The relevant part of my code is following:
if request.env.web2py_runtime_gae: # if running on Google App Engine
from gluon.contrib.login_methods.gae_google_account import GaeGoogleAccount
auth.settings.login_form = GaeGoogleAccount()
from gluon.contrib.gql import gae
auth.define_tables() # creates all needed tables
db.define_table('todos', Field('name','string'),
Field(gae.ReferenceProperty(auth_user, required=True,
collection_name='todos'))
)
And the traceback is this:
Traceback (most recent call last):
File "/Users/lauer/web2py/gluon/restricted.py", line 178, in restricted
exec ccode in environment
File "/Users/lauer/web2py/applications/web2pytodo/models/db.py",
line 76, in <module>
Field(gae.ReferenceProperty(auth_user, required=True,
NameError: name 'auth_user' is not defined
Maybe the entity class is not defined at the time of the reference? I
created an user, but still isn't working.
When this mini-project is finished I plan to release the source. I
think that a working example of this technique woukd be interesting
for reference.
Traceback (most recent call last):
File "/Users/lauer/web2py/gluon/restricted.py", line 178, in restricted
exec ccode in environment
File "/Users/lauer/web2py/applications/web2pytodo/models/db.py",
line 76, in <module>
Field(gae.ReferenceProperty(db.auth_user._tableobj))
File "/Users/lauer/web2py/gluon/sql.py", line 2648, in __init__
self.name = fieldname = cleanup(fieldname)
File "/Users/lauer/web2py/gluon/sql.py", line 574, in cleanup
if re.compile('[^0-9a-zA-Z_]').findall(text):
TypeError: expected string or buffer