[This is starting to veer *way* off-topic, and might be more
appropriate on the GAE list. My apologies]
On Jan 3, 5:00 pm, "sudhakar m" <
sudhakar...@gmail.com> wrote:
(OK, this was from a different message):
> Yes I did a small test with a simple model. It was taking around
> 1sec/request for single write on an entity. I am not sure if that is
> acceptable in real world apps. As Robin mentioned earlier, we can use batch
> write to speed up writes. Probably read should be much faster & it can
> cached to have even better response
From what I've gathered, avoid entity groups, pretty much at all
costs. Use the bulk uploader if you can. And, really, don't plan on
updating more than 1 or 2 entities per request.
> Thanks James for sharing the info.
No problem. And remember, like everyone else, I'm still getting my
head wrapped around GAE as well.
> Set up the models with the suggested work-
>
> > arounds. Bulk upload a few thousand records. Set up a page or three
> > that run the most complicated queries you expect to see. Then check
> > your logs.
>
> I reached the same stage 2 days back. I designed models in web2py way using
> the newly introduced many-to-many from trunk. The good thing about the new
> many-to-many is that it eliminates the need for join table. When i finished
> my bare-bones prototype design, I ended up in designing model's very slim &
> sleek. I mean I used 6-7 many-to-many's & few one-to-many's & it drastically
> reduced no of tables in my final design. I would say it was rather
> un-conventional design, which followed neither RDBMS nor GAE's flat model. I
> didnt have any data duplication (except for the key's) at the same time
> having the benifits of both worlds.
If it's fast enough for you, then great! Run with it. But try not to
get hung up on data duplication. That's one thing I've learned from
google's engineers: don't sweat it (even though maintaining multiple
copies of the same data is a pain). [That doesn't apply in an RDBMS,
of course]
> But after little thought I started
> worrying about text-field being used for join. Although it was a very good
> idea, its very much in early stage & there is no benchmarks about the
> performance, considering the fact that text-fields are not indexed.
Have you tried running any benchmarks yet? (BTW, this sort of thing
*really* needs to be run on google's servers. The fake datastore they
use in the SDK is awful).
> I felt
> ListProperty<
http://code.google.com/appengine/docs/datastore/typesandpropertyclass...>to
> be a much better choice.
At this point, I still basically have JOIN tables, sort of. They're
meaningful tables (say, the Team) that I'll be querying for
themselves. Each Team will have a ListProperty of KeyProperty's back
to its Players (likewise for the Players back to the Teams they're
on), and Matches would have a ReferenceProperty back to each team that
played (maybe Home and Visitor, or some such).
(Huh. I'm not doing anything with sporting events at all, but this
pattern matches up almost precisely with my problem domain. I wonder
how common it really is).
So, if I have a set of matches and want to retrieve the players, I
have a lot of querying/joining/reference-following to do. And what
happens if players get traded in the middle of the season? It would
probably make more sense to just take the players (and their status)
for both teams in a given match, pickle that, and store it in a Blob.
If you have to worry about those things.
In my case, I can query for a Team, then use Ajax to load the players
and matches (basically grabbing one record per request) and build a
tree that way.
It just depends on what you need. GAE does force you to do more up-
front analysis and design than I'm used to.
>> Based just on what I've seen on the GAE mailing list, I think you'll
>> need to make the same switch I did.
>
> I am thinking to staying more close to GAE. I know it will be pain to work
> at the lower level directly at GAE API without any frame work. But again, If
> I end up hacking both web2py & webapp, it will become equally difficult to
> maintain (oops this is my personal opinion).
I wouldn't want to mix/match those, either.
> I am yet to check out other big
> beast Django. I have heard that it plays nice with GAE, but I am still
> skeptical to use it in my app as it's too heavy & learning curve will be
> very steep (I especially hate it, if i have to learn for months to develop a
> single app)when compared to web2py
I know conventional wisdom says to use django. But in and of itself,
it's really focused on a very niche problem domain, which doesn't
match my needs at all. After they took out the pieces that just won't
work on GAE, it seemed pretty useless to me.
And then tons of people are trying to install 1.0 (instead of the more-
or-less 0.96 that GAE provides), and failing. There seem to be
several projects around to make this work, but I haven't had the
patience/motivation yet to actually try it.
> > [Later, after I'd trimmed down my web2py installation immensely, so I
> > wasn't as worried about the file count limit, I switched that to a
> > GaeModels folder with an __init__.py that imports all my models and
> > then broke each model into its own class. I'm mentioning this only
> > because you said you're new to python, so I'm guessing you haven't
> > seen this trick yet].
>
> Yes very much. I havent even started using modules!! I would say that I am
> still evauating how to extract best out of web2py & GAE.
Don't neglect the python side of things ;-). There's tons of gooey
goodness in this language.
> > I don't think I've ever used SQLFORM. I'm perfectly fine with
> > building my own forms, saving my own data, and doing my own
> > validation.
>
> Out of my curiosity I have few questions.
>
> ReferenceProperty &
> <
http://code.google.com/appengine/docs/datastore/typesandpropertyclass...>
> SelfReferenceProperty<
http://code.google.com/appengine/docs/datastore/typesandpropertyclass...>arent
> used for defining relations. Instead IntegerProperty is used.
> Conventional representation on very-unconventional DB. Are you facing any
> problems in this. Are you defining model web2py conventinal way or with
> webapp api?
I'm using google's raw datastore api (google.ext.db). I gave up on
web2py's style of models when I really needed a ListProperty of
KeyProperty's.
No biggy. I can write to google's "low-level" ORM (I think they
actually snagged the interface from django) where I need it, then use
web2py's when I don't. (Actually, I like google's ORM better, so I've
wound up using it pretty much exclusively). And still keep the rest
of web2py's goodness.
> How did you approach many-to-many relationship in your design?
I cheat. :-D
> Are you using Expando<
http://code.google.com/appengine/docs/datastore/expandoclass.html>property
> in your models along with web2py.
I haven't come across a situation where I could find any use for it.
Yet.
> I think this is a cool feature & ofcourse its unconventional again.
I agree totally. One of those examples of tradeoffs with an RDBMS.
"If you try to JOIN tables, the performance is going to be awful.
Let's not even talk about transactions. But, hey, try doing *this*
with SQL Server!" As long as you will have the penalties, no matter
what, you might as well take advantage of the benefits.
>
> What is the final feature set for web2py on GAE.
I'm definitely not the person to ask about this. I've done so much
heavy customization (mainly yanking things out) that I haven't
switched versions in months. I should probably post my changes back
somewhere (be happy to, if anyone's interested), but they aren't
anything that will wind up in the trunk, and I'm not about to suggest
branching.
> As far as I can list, I can
> list the following things
> 1. Small codebase (one can always see the code for learning)
> 2. Automatic migration
> 3. Clean templating
> 4. SQLFORM ofcourse ( speeds up prototyping !!)
Like I think I said, it would be *very* interesting to see how this
works using GAE's models instead of web2py's. (Or rather, how hard it
would be to make it work).
> 5. Multiple db support (may come in handy if we want to sync GAE with
> external db. Honestly didnt think of it b4 writing this)
Do you mean having one app running on GAE, running against BigTable,
with another running on your own host, using a different back-end?
I haven't really considered it (all that much), but that does sound
powerful.
> 6. Admin UI (yes I hacked it & hosted in a remote shared free host. So
> deoloyment is single click again)
Sweet! That sounds like a patch you should send.
It does remind me of one more piece of advice. You're probably better
off developing against the SDK server, rather than web2py's. (You'll
pretty much have to do that if you switch to google's Models). I
don't remember ever hitting anything I could specifically put my
finger on, but I never felt comfortable developing against, say,
sqlite with web2py's server, then publishing to google's servers.
>
> Anything else in feature list?
Hmm. I'm sure the people with more web2py experience than I can give
a more authoritative list. But, off the top of my head:
* Heavily tested code, that's been looked at by a lot of people (not
as many as django, but the parts I've compared are also much more
readable)
* *Much* higher level abstractions than webapp. Google's pretty much
deprecated that approach.
* Quite a lot of built-in security that's just silly to try to re-
invent
* I haven't really checked out T2 and T3, but they sound extremely
interesting
* Easy, intuitive access to things like REQUEST and RESPONSE.
* Responsive, friendly community. That may just be a side-effect of
python...it seems like *all* python programmers are friendly and
helpful. Maybe because we aren't all stressed out about all the
nonsense our programming language forces on us? <G>
>. As of now I am prepared to sacrifice above
> for performance (pure academic intreset in this).
*If* it turns out that you have performance problems (I've been wrong
before. Premature optimization is the root of all evil!), I really
recommend you just swap out the database layer. Maybe put a light
wrapper over web2py's ORM and only access it. As needed, you can
shift that wrapper to use GAE's, and the calling code will never know
you changed anything.
That may be the easiest approach to using SQLFORM: have wrapper
classes over GAE's ORM with the same interface as web2py's ORM, and
feed those to SQLFORM. Like I said, I haven't really looked at
SQLFORM at all, so I have no idea how much work would be involved.
Or maybe just forget about web2py's ORM and use GAE's. Just because
that part's a performance brick wall doesn't mean you should also
scrap the rest of it.
> If I could find some way
> of unobtrusively using GAE's features, I will certainly jump back ;)
It's no big deal. The customizations I've made are mainly my own
personal quirks (simplejson is included with GAE's django, so I don't
also need the version web2py includes in contrib. gluon.import_all
imports a lot of pieces that don't exist on GAE, so I got rid of them
because I got tired of seeing the error messages at startup. Etc).
Hmm. Simple example. This is old code, so no promises about whether
it still works (or is actually worth looking at):
In applications/init/modules/GaeModels I have email_list.py:
#! /usr/bin/env python
''' People who want to be notified about updates '''
from google.appengine.ext import db
import applications.init.modules.Base as Base
class email_list(db.Model, Base.BasePermission):
nickname = db.StringProperty(default = "Anonymous")
email_address = db.EmailProperty(required=True)
musician = db.BooleanProperty(default=False)
validated = db.BooleanProperty(default=False)
opted_in = db.DateTimeProperty(default=None)
In my wrapper class, one of the methods that accesses that:
class MailingListSignUp(Base.Base):
...
def BasicAddToMailingList(self):
''' If the user hasn't already declined to be a part of this,
request to
participate '''
existing_requests = GaeModels.email_list.all().filter
('email_address',
self.email_address)
# For now, if they've requested once, don't send another email.
# This is a compromise that probably needs to be reconsidered
# Then again, the email list is really a stop-gap
for existing_request in existing_requests:
raise MyExceptions.EmailRejected(self.email_address)
list_add_request = GaeModels.email_list(email_address =
self.email_address)
if self.nickname:
list_add_request.nickname = self.nickname
list_add_request.musician = self.musician
list_add_request.put()
return list_add_request.key()
My Controller can make an instance of that, call BasicAddToMailingList
(), do whatever it wants with the result, and pass its results on to
the View. It has no idea which ORM I'm using.
Not perfect, but it strikes me as tons better than just dropping
web2py completely.
Good luck,
James