Anvanced applications in gae

56 views
Skip to first unread message

Carles Gonzalez

unread,
Jun 21, 2010, 10:25:28 AM6/21/10
to web...@googlegroups.com
Hi,

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!

mdipierro

unread,
Jun 21, 2010, 12:43:33 PM6/21/10
to web2py-users
Probably it would not be hard to implement. I will look into this next
week but if somebody sends me a patch before that I will take it.

Massimo

Carles Gonzalez

unread,
Jun 21, 2010, 12:55:56 PM6/21/10
to web...@googlegroups.com
Ok, thanks! I would like to make the patch myself, but the innards of
web2py are somewhat complex...

Thanks again, Carles.

mdipierro

unread,
Jun 21, 2010, 1:03:22 PM6/21/10
to web2py-users
The only file you need to look into is gluon/contrib/gql.py

specifically the select() function which calls filter returns the Rows
object

On Jun 21, 11:55 am, Carles Gonzalez <carle...@gmail.com> wrote:
> Ok, thanks! I would like to make the patch myself, but the innards of
> web2py are somewhat complex...
>
> Thanks again, Carles.
>

Carles

unread,
Jun 21, 2010, 3:35:16 PM6/21/10
to web...@googlegroups.com
Ok, I'll try.

Carles

Matt

unread,
Jun 21, 2010, 7:42:53 PM6/21/10
to web2py-users
Any chance this could be considered as well?

Currently the DAL doesn't allow you to set the parent which is
required for GAE entity groups.

http://groups.google.com/group/web2py/browse_thread/thread/3c11deb2bfadf207/96a4324e5fd0cf71?lnk=gst&q=GAE+parent#96a4324e5fd0cf71

On Jun 22, 7:35 am, Carles <carle...@gmail.com> wrote:
> Ok, I'll try.
>
> Carles
>

Carles Gonzalez

unread,
Jun 22, 2010, 1:56:44 PM6/22/10
to web...@googlegroups.com
My english is horrible, an maybe it wasn't clear, but that was exactly
my problem :).

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

unread,
Jun 23, 2010, 10:11:44 AM6/23/10
to Carles Gonzalez, Lliata Web2py
Sorry but, any thoughts?

Carles

Yarko Tymciurak

unread,
Jun 23, 2010, 1:02:05 PM6/23/10
to web2py-users

On Jun 23, 9:11 am, Carles <carle...@gmail.com> wrote:
> Sorry but, any thoughts?

Have you looked at http://www.web2py.com/book/default/section/6/6?search=puppy

or http://www.web2py.com/book/default/section/6/9?search=puppy (you
could have a relationship field if you _needed_, or
you could simply have a parent / child table, with id of the parent in
a parent field, id of a child in child field)..

I'm not sure I know what you want / why you want this, why an
attribute on a field is "special" for your request....

- Yarko

>
> Carles
>
> El 22/06/2010, a las 19:56, Carles Gonzalez <carle...@gmail.com> escribió:
>
>
>
> > My english is horrible, an maybe it wasn't clear, but that was exactly
> > my problem :).
>
> > 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?
>
> > On Tue, Jun 22, 2010 at 1:42 AM, Matt <mjwat...@gmail.com> wrote:
> >> Any chance this could be considered as well?
>
> >> Currently the DAL doesn't allow you to set the parent which is
> >> required for GAE entity groups.
>
> >>http://groups.google.com/group/web2py/browse_thread/thread/3c11deb2bf...

mdipierro

unread,
Jun 24, 2010, 8:27:30 AM6/24/10
to web2py-users
thinking about how to handle this...

On Jun 22, 12:56 pm, Carles Gonzalez <carle...@gmail.com> wrote:
> My english is horrible, an maybe it wasn't clear, but that was exactly
> my problem :).
>
> 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?
>
> On Tue, Jun 22, 2010 at 1:42 AM, Matt <mjwat...@gmail.com> wrote:
> > Any chance this could be considered as well?
>
> > Currently the DAL doesn't allow you to set the parent which is
> > required for GAE entity groups.
>
> >http://groups.google.com/group/web2py/browse_thread/thread/3c11deb2bf...

Carles Gonzalez

unread,
Jun 24, 2010, 9:22:00 AM6/24/10
to web...@googlegroups.com
Thanks!

dlypka

unread,
Jun 24, 2010, 7:21:24 PM6/24/10
to web2py-users
I've done a parent - to - many child GAE / web2py implementation using
SelfReference fields (or you can use Reference as well) using the
technique for adding native GAE fields into a web2py table definition.

It gives fantastic retrieval performance because GAE automatically
adds the link from the child back into the parent's reference list
at the time you create each child. When you later query for the
parent, voila GAE retrieves all the child entities along with it in
one backend call!

Hopefully this technique is relevant to your application.

I also develop some other tricks for inheriting native GAE classes
into your web2py model, though
this is less attractive perhaps now that GAE native properties can be
directly declared in web2py tables.

- Dave Lypka.

Carles Gonzalez

unread,
Jun 24, 2010, 8:41:04 PM6/24/10
to web...@googlegroups.com
Very interesting!

I'll try tomorrow.

Thanks a lot, Dave.

Carles Gonzalez

unread,
Jun 24, 2010, 8:43:23 PM6/24/10
to web...@googlegroups.com
Not to be annoying, but can you post an example?

Just to organize the things in my head...

Thanks again.

dlypka

unread,
Jun 25, 2010, 2:42:14 PM6/25/10
to web2py-users
OK will do - please give me a few days...

Carles

unread,
Jun 25, 2010, 2:48:33 PM6/25/10
to web...@googlegroups.com, web2py-users
Thanks a lot Dave.

There isn't a deadline, tale your time :)

Carles

dlypka

unread,
Jun 26, 2010, 2:52:14 AM6/26/10
to web2py-users

For starters:

Refer to
http://arbingersys.blogspot.com/2008/04/google-app-engine-one-to-many-join_26.html?showComment=1244344382942#c5661660955046324965

And Here is the posting about using native GAE properties

http://groups.google.com/group/web2py/browse_thread/thread/7112ef7dee1ccf32/d2b0d24c0e499924?lnk=gst&q=native#d2b0d24c0e499924

So for example you would do

from gluon.contrib.gql import gae
:
:
db.define_table('ChildItem',
# NOTE: web2py provides the 'id'
column automatically
db.Field('idParentFolder','reference
MyParent'),
db.Field('name','text'),
db.Field('gaeParentInstance',
gae.ReferenceProperty(MyParent,
required=False,
collection_name='linksFromChildItemToParent')))

)

and define the parent class in a similar fashion.

It is also necessary to add some plumbing to find and track the native
GAE references
which lie underneath the web2py sql objects because the native refs
have to be
put into the collections.

I'll provide more details in some followup posts.

Carles Gonzalez

unread,
Jun 26, 2010, 5:48:21 AM6/26/10
to web...@googlegroups.com
Very interesting, i didn't know about collection_name and the associated query.

You are shedding some light on doing relationships the GAE way.

Thanks again.

dlypka

unread,
Jun 27, 2010, 10:36:52 AM6/27/10
to web2py-users
Assuming you have
try:
from gluon.contrib.gql import * # if running on Google App
Engine
except:
db=SQLDB('sqlite://storage.db') # if not, use SQLite or
other DB - Used by T2
datastoretype = 'SQL'
else:
db=GQLDB() # connect to Googl
datastoretype = 'GAE'

# So now, db is the GAE db

# To use those Collections in the Reference properites, you need to
insert NATIVE GAE references,
# so you need to somehow find the GAE entity instance reference given
a web2py sql row

# Here is the 'Stargate / wormhole' code which takes you from web2py
back down into the native GAE Datastore alternate universe:


# So if you have a web2py table name 'ChildTable':

web2pyChildTableClass = db.ChildTable # gives the web2py Table
class

theNativeGAEChildTableClass = web2pyChildTableClass._tableobj #
magic... into GAE

# ================================================================

# Now do a native GAE query to find the native GAE instance so it
# can be put into the Reference collection:

nativeGAE ChildTableQuery = theNativeGAEChildTableClass.all()

nativeGAEChildTableQuery.filter('id =', 25) # get for id = 25

nativeresults = nativeGAEChildTableQuery.fetch(limit=1)

myGAENativeChild = nativeresults[0]

# Now myGAENativeChild can be inserted into the native GAE Reference
collection

- Dave Lypka

On Jun 26, 5:48 am, Carles Gonzalez <carle...@gmail.com> wrote:
> Very interesting, i didn't know about collection_name and the associated query.
>
> You are shedding some light on doing relationships the GAE way.
>
> Thanks again.
>
>
>
> On Sat, Jun 26, 2010 at 8:52 AM, dlypka <dly...@gmail.com> wrote:
>
> > For starters:
>
> > Refer to
> >http://arbingersys.blogspot.com/2008/04/google-app-engine-one-to-many...
>
> > And Here is the posting about using native GAE properties
>
> >http://groups.google.com/group/web2py/browse_thread/thread/7112ef7dee...

Carles Gonzalez

unread,
Jun 27, 2010, 11:44:21 AM6/27/10
to web...@googlegroups.com
One word: WOW!

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.

mdipierro

unread,
Jun 27, 2010, 11:54:44 AM6/27/10
to web2py-users
I will wait for a patch from Dave. He knows more than I know about
this.

Massimo

dlypka

unread,
Jun 27, 2010, 12:36:25 PM6/27/10
to web2py-users
I am not sure what functionality is being requested to add GAE
specific support to
IS_IN_DB.
My discussion has been about high performance links from parent to
children.
What native GAE object(s) would you need to check in IS_IN_DB ?

Anyway, one nice to have patch would be to have insert() return the
native GAE ref
to the newly inserted row, so that the GAE ref would be immediately
available
for insertion into the native Reference collection.

That would reduce the need for querying for the native reference as in
my previous post.

So, in gql.py
in the method
def insert(self, **fields):

at the last line where it does
return rid

I suggest we need to also return tmp
because tmp is in fact the native GAE instance.

I suppose adding a field to gluon.sql.Reference is a 'non starter'.

Maybe just add a new property dynamically to the row
We could call it 'nativeRef'

Would it be something like:
self.nativeRef = tmp # Python can add new properties 'on-the-
fly', right?

as the new 2nd last statement of insert()?

Carles Gonzalez

unread,
Jun 27, 2010, 1:15:17 PM6/27/10
to web...@googlegroups.com
I thought that IS_IN_DB() could do all the heavy lifting, searching by
gae keys instead of integers and updating references. That way we
wouldn't lose SQLFORM and the api would be the same on both on SQL and
GQL.

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.

mdipierro

unread,
Jun 27, 2010, 3:28:37 PM6/27/10
to web2py-users
> Maybe just add a new property dynamically to the row
> We could call it 'nativeRef'
>
> Would it be something like:
>     self.nativeRef = tmp     # Python can add new properties 'on-the-fly', right?
>
> as the new 2nd last statement of insert()?

If that is useful we can do it. I just did it in trunk so you can test
it but I called self._last_reference to avoid possible naming
conflicts.

Massimo

dlypka

unread,
Jun 27, 2010, 5:36:36 PM6/27/10
to web2py-users
Great. Thanks so much!

However, I've never accessed the 'trunk' before.

I don't think I have access.

Do I need to do a get from Mercurial source control?

I have WING IDE, which I believe supports Mercurial.
Message has been deleted

Yarko Tymciurak

unread,
Jun 27, 2010, 6:19:39 PM6/27/10
to web2py-users

On Jun 27, 4:36 pm, dlypka <dly...@gmail.com> wrote:
> Great. Thanks so much!
>
> However, I've never accessed the 'trunk' before.
>
> I don't think I have access.

You do - it's distributed SCM - you have read-only access
>
> Do I need to do a get from Mercurial source control?
>
> I have WING IDE, which I believe supports Mercurial.

Wing supports mercurial thru a wing interface - you have to have
mercurial (which is a python app) on your system for wing to call it.

Get murcurial at http://mercurial.selenic.com/

Then you can get the trunk from http://code.google.com/p/web2py/ -
the command line for getting a copy ("clone") of the trunk is there:

hg clone http://web2py.googlecode.com/hg/ web2py-trunk # or
whatever local directory you want to put it in

Once you do that, you can just go into that directory, and issue:

hg status # to see if you made any local changes
hg commit # to commit local changes
hg pull # to update from where you cloned this - i.e. to pull in
changes
# or, if you've made changes locally:
hg merge # to get and merge any changes...

Since cloning is quick and easy, you want to consider keeping a
"clean" clone of the master, and for any local work / tests you have,
make a local clone, e.g. from where you can see th web2py-trunk that
you cloned from google code:

hg clone web2py-trunk my-patch-test

This will make it easy to make changes that are small, that you can
easily throw away, and keep a "clean" copy locally if you want to
start over on a test, or try another test.

If you prefer "visual" tools, there is gnome integration on ubuntu,
and for windows you might enjoy TortoiseHG: http://tortoisehg.bitbucket.org/

It's quick; it's easy; it's a nice way to keep your work under hg
(which - as you've noticed - if your project is under hg, then you can
see changes from wing).

Regards,
- Yarko

dlypka

unread,
Jun 27, 2010, 7:32:50 PM6/27/10
to web2py-users
Thanks for the detailed instructions - will do.

On Jun 27, 6:19 pm, Yarko Tymciurak <resultsinsoftw...@gmail.com>
wrote:
> On Jun 27, 4:36 pm, dlypka <dly...@gmail.com> wrote:
>
> > Great. Thanks so much!
>
> > However, I've never accessed the 'trunk' before.
>
> > I don't think I have access.
>
> You do - it's distributed SCM - you have read-only access
>
>
>
> > Do I need to do a get from Mercurial source control?
>
> > I have WING IDE, which I believe supports Mercurial.
>
> Wing supports mercurial thru a wing interface - you have to have
> mercurial (which is a python app) on your system for wing to call it.
>
> Get murcurial athttp://mercurial.selenic.com/
>
> Then you can get the trunk fromhttp://code.google.com/p/web2py/ -
> the command line for getting a copy ("clone") of the trunk is there:
>
> hg clonehttp://web2py.googlecode.com/hg/ web2py-trunk   # or

dlypka

unread,
Jun 28, 2010, 12:57:27 AM6/28/10
to web2py-users
Correction upon actually testing code in trunk:

myParentNativeRef = myParent._last_reference # This uses
Massimo's mod in the trunk...

should be:

myParentNativeRef = myParent._table._last_reference # This uses
Massimo's mod in the trunk...

On Jun 27, 6:03 pm, dlypka <dly...@gmail.com> wrote:
> # NOTE: I have *NOT* tested the following code
> #       because this is greatly simplified from my actual code,
> #       so some debugging may be necessary to get it to work
> #
> # The following assumes that gql.py has been modified to add a
> statement to method
> #  insert():
> #     add a new statemtent before the final return statement as
> follows:
> #        self._last_reference = tmp  # <==== Add this new statement,
> as per Massimo's mod in the trunk ====
> #        return rid
>
> # Here are the sample tables to create:
>
>     db.define_table('ParentTable',
>                     # NOTE: web2py provides the 'id' column
> automatically
>                     db.Field('name','text')
>                    )
>
>     db.define_table('ChildTable',
>                     # NOTE: web2py provides the 'id' column
> automatically
>                      db.Field('idParentFolder','reference
> ParentTable'),
>                      db.Field('age','integer'),
>                      db.Field('name','text'),
>                      db.Field('parentLink',
> gae.ReferenceProperty(ParentTable, required=True,
>                                collection_name='ChildCollection') #
> native link to parent
>                     )
>
> # Here is the code to insert a parent and a child
>
>     myParent = db.ParentTable.insert(name='Bill')
>     myParentNativeRef = myParent._last_reference  # This uses
> Massimo's mod in the trunk...
>     myParentid = myParent.id
>
>     # NOTE: if myParentNativeRef is not available, then instead you
> can
>     #       use the technique in my previous forum msg to query for
> the native ref and id of the Parent
>
>     myChild = db.ChildTable.insert(age = 9, name = 'Johnny',
>                                    idParent = myParentid,
>                                    parentLink = myParentNativeRef)
>
>    # -------- End of code to insert data
> ------------------------------------------------------------
>
>    #
> --------------------------------------------------------------------------- ----------------------
>    #   Here is the code to retrieve the parent and children using the
> native references
>    #   Performance is very fast because GAE does this in a single call
> to the Datastore:
>
>      myParent = db(db.ParentTable.name=='Bill').select()  # This is a
> web2py query on steroids...
>
>      for child in myParent.ChildCollection:
>          myChildName = child.name
>          myChildAge = child.age
>
> # ----------------------  End of Sample code
> -------------------------------------------------------------------

dlypka

unread,
Jun 28, 2010, 1:04:04 AM6/28/10
to web2py-users
OK I downloaded the trunk and tested this mod.

myParent = db.ParentTable.insert(name='Bill')
myParentNativeRef = myParent._table._last_reference

works

Thanks again.

On Jun 27, 3:28 pm, mdipierro <mdipie...@cs.depaul.edu> wrote:

Carles Gonzalez

unread,
Jun 30, 2010, 4:25:33 PM6/30/10
to web...@googlegroups.com
Hi, i was trying this technique but i'm getting this traceback when
using gae_google_account:

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?

mdipierro

unread,
Jun 30, 2010, 4:39:39 PM6/30/10
to web2py-users
You are right... fixing it in trunk..1..2..3..done. Please check it.

Massimo

Carles Gonzalez

unread,
Jun 30, 2010, 4:56:33 PM6/30/10
to web...@googlegroups.com
Now is working. Thanks, let's continue testing...

Carles Gonzalez

unread,
Jun 30, 2010, 5:15:31 PM6/30/10
to web...@googlegroups.com
Sorry, but I've encontured another error.

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.

mdipierro

unread,
Jul 1, 2010, 1:32:43 AM7/1/10
to web2py-users
I think,

Field(gae.ReferenceProperty(auth_user,...)

should be


Field(gae.ReferenceProperty(db.auth_user._tableobj,....)
> On Wed, Jun 30, 2010 at 10:56 PM, Carles Gonzalez <carle...@gmail.com> wrote:
> > Now is working. Thanks, let's continue testing...
>

Carles Gonzalez

unread,
Jul 1, 2010, 4:23:30 AM7/1/10
to web...@googlegroups.com
Tested and now the error is:

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

mdipierro

unread,
Jul 1, 2010, 8:03:12 AM7/1/10
to web2py-users
Sorry...

Field('fieldname',type=gae.ReferenceProperty(db.auth_user._tableobj,....)

On 1 Lug, 03:23, Carles Gonzalez <carle...@gmail.com> wrote:
> Tested and now the error is:
>
> 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
>

Carles Gonzalez

unread,
Jul 1, 2010, 9:42:19 AM7/1/10
to web...@googlegroups.com
Ah... Ok, that makes much more sense.

dlypka

unread,
Jul 5, 2010, 5:53:52 AM7/5/10
to web2py-users
Here is some sample code using these features.
I have tested it, although the following is slightly edited from what
I tested:

try:
from gluon.contrib.gql import * # if running on Google App
Engine
except:
db=SQLDB('sqlite://storage.db')
datastoretype = 'SQL'
else:
db=GQLDB() # connect to GAE
datastoretype = 'GAE'

from gluon.contrib.gql import gae

def TestNativeGAE(request, response, session):

if not 'ParentTable' in db.tables:
db.define_table('ParentTable',
# NOTE: web2py provides the 'id' column automatically
db.Field('nKey','integer'),
db.Field('name','text')
)
if not 'ChildTable' in db.tables:
db.define_table('ChildTable',
# NOTE: web2py provides the 'id' column automatically
db.Field('idParentFolder','reference ParentTable'),
db.Field('age','integer'),
db.Field('name','text'),
db.Field('parentLink',
gae.ReferenceProperty(db.ParentTable._tableobj, required=True,
collection_name='ChildCollection'))
)

# Here is the code to insert a parent and a child

myParent = db.ParentTable.insert(nKey=1, name='Bill')
myParentNativeRef = myParent._table._last_reference
myParentid = myParent.id
myname = myParentNativeRef._name
myname2 = myParentNativeRef.name
myParentnKey = myParentNativeRef.nKey

# NOTE: if myParentNativeRef is not available, then instead you
can
# use the technique in my previous forum msg to query for
the native ref and id of the Parent

myChild = db.ChildTable.insert(age = 9, name = 'Johnny',
idParent = myParentid,
parentLink = myParentNativeRef)

# -------- End of code to insert data
------------------------------------------------------------

#
-------------------------------------------------------------------------------------------------
# Here is the code to retrieve the parent and children using the
native references
# Performance is very fast because GAE does this in a single call
to the Datastore:


#rows = db(db.ParentTable.name ==
'Bill' ).select(db.ParentTable.ALL) # finds nothing for some reason
rows = db(db.ParentTable.id==myParentid).select()
myParent2 = rows[0]
#myNativeParent2 = myParent2._table._last_reference # Would be
nice to have this work as well but at the moment it does not work....

theNativeParentClass = db.ParentTable._tableobj

nativeParentTableQuery = theNativeParentClass.all()

#nativeParentTableQuery.filter('name =', 'Bill') # This filter
finds nothing!! Some problem with text keys ???? < ======
#nativeParentTableQuery.filter('id =', myParentid) # This filter
finds nothing because native GAE Entity has no auto generated id
nativeParentTableQuery.filter('nKey =', myParentnKey)
nativeresults = nativeParentTableQuery.fetch(limit=1)

myGAENativeParent = nativeresults[0]

for child in myGAENativeParent.ChildCollection:
myChildName = child.name
myChildAge = child.age

return dict(form=child.name)
Reply all
Reply to author
Forward
0 new messages