The code demonstrated was obviously quickly written code. A better solution would be to loop, attempting to get a few hundred rows from the table, updating those, and doing it again until the get doesn't return any rows. that way you are done.
It appears that Google's AppEngine is not designed or streamlined for inserting or updating lots of data. If you are writing an application in which there is a lot of updating the data, modifying records and stuff, then maybe you are using the wrong framework.
Using the reference property is a way to provide a "virtual" join.
The solution using a reference would be to do:
product = Product.all().filter("name =", product_name).get()
product.name = "New Name"
The get would however become
Purchase.all().filter("product =", product).filter(customer =", customer).fetch(1000)
which again looks fine, but what about when you are looking at a single customer's order history?
purchases = Purchase.all().filter("customer =",customer).fetch(1000)
for purchase in purchases:
output(
purchase.product.name,...)
At this point, everytime you want to display the name, your call to purchase.product does a lookup in the BigTable to get the product out, and that is going to take time.
Because of the way BigTable is organised, that data may be on a completely differant server, in a different tablet, giving you a high cost to get that data out. That might be fine for one or two properties, but as your data model gets more expensive, so will each call, and your application will not scale.
The viewpoint for building stuff on Google's AppEngine is that you should be expecting to do millions of page views for every update or edit. Thats what the underlying datastore is designed to do.
Michael