The App Engine datastore API comes with a wide range of Property classes you can use to represent properties on your datastore models. Occasionally, though, you'd like to do something that the designers didn't think of. Fortunately, it's really easy to extend the Datastore API with custom Property classes. In this blog post, we'll demonstrate how to write your own Property class to store Python's decimal data type.

The App Engine datastore API comes with a wide range of Property classes you can use to represent properties on your datastore models. Occasionally, though, you'd like to do something that the designers didn't think of. Fortunately, it's really easy to extend the Datastore API with custom Property classes. In this blog post, we'll demonstrate how to write your own Property class to store Python's decimal data type.


The Property interface is documented here, but there are two essential methods our DecimalProperty must override: get_value_for_datastore, and make_value_from_datastore. We also need to declare one field, data_type, that specifies the data type our property class will contain. Let's start with a straightforward implementation:



class DecimalProperty(db.Property):
data_type = decimal.Decimal

def get_value_for_datastore(self, model_instance):
return str(super(DecimalProperty, self).get_value_for_datastore(model_instance))

def make_value_from_datastore(self, value):
return decimal.Decimal(value)

Note that in the case of get_value_for_datastore, we used super to call the parent class implementation, which handles the details of actually storing and retrieving the data stored in the model. We then simply convert the value to a string for storage in the datastore. In make_value_from_datastore, we reconstruct a Decimal object from the stored string.


That's all that's required for a basic property class! There is something missing from our example, though: We don't perform any validation to make sure that the user actually passed in a Decimal object. To do that, we override the validate method:



def validate(self, value):
value = super(DecimalProperty, self).validate(value)
if value is None or isinstance(value, decimal.Decimal):
return value
elif isinstance(value, basestring):
return decimal.Decimal(value)
raise db.BadValueError("Property %s must be a Decimal or string." % self.name)

Again we start by calling the parent class's implementation, which performs some basic validity checks. Then we check if the value is a Decimal - in which case we return it - or a string, in which case we convert it to a decimal and return it. If the value is invalid, we raise a BadValueError.


Using our property class is as simple as using any other one:



class MyModel(db.Model):
a_decimal = DecimalProperty()

model = MyModel()
model.a_decimal = decimal.Decimal("123.45")
model.put()


For a more in depth treatment of writing your own property class, see the article by Rafe Kaplan, Extending Model Properties.



Greetings App Engine developers! We're pleased to announced the availability of a new Java SDK, available for download here. This is largely a bugfix release, but there are a few new features we think you'll be excited to get your hands on ...
Greetings App Engine developers! We're pleased to announced the availability of a new Java SDK, available for download here. This is largely a bugfix release, but there are a few new features we think you'll be excited to get your hands on:

  • The appcfg upload tool includes proxy support.

  • JDO and JPA support an extension that lets you mark individual fields as "unindexed."

  • At long last, the dev appserver has a data viewer. Start your app locally and point your browser to http://localhost:8080/_ah/admin to check it out.

  • The local datastore now has the same transaction behavior as the production datastore (more info: http://code.google.com/p/googleappengine/issues/detail?id=1411)

  • You can issue ancestor queries inside transactions.



For a full list of features, see the release notes.

The latest release of Python SDK 1.2.3, which introduced the Task Queue API and integrated support for Django 1.0, may have received a lot of attention, but there have been a number of other notable launches and events since our last update. Several of these are summarized below.

The latest release of Python SDK 1.2.3, which introduced the Task Queue API and integrated support for Django 1.0, may have received a lot of attention, but there have been a number of other notable launches and events since our last update. Several of these are summarized below.

A Day in the Cloud

On June 24th, Google Apps and Virgin America invited people from around the world to participate in a one-day online scavenger hunt called Day in the Cloud. Competitors were each given one hour to solve various puzzles and find answers to a host of trivia questions, and prizes were awarded to the top five scorers. The site was hosted on App Engine's scalable infrastructure. For more information on the challenge, including photos and videos of participants competing mid-flight, check out the official Day in the Cloud Lounge.

Scaling series

App Engine enables you to deploy and run your Python- and Java-based web applications on Google's highly scalable infrastructure. There are a number of ways to optimize the performance of an application running on App Engine, some obvious and others more subtle. With this in mind, we recently released a series of articles promoting tips and tricks that you can use to make best use of resources like memcache and prevent potential issues such as datastore contention.

We also updated the articles listing since we recognized that the growing number of articles added since April 2008 (over 35 by last count) made it difficult to find content on a specific topic. The new listing allows you to filter the list of articles based on a particular tag or label, so you can easily find all articles related to the datastore, for example.

As always, we are interested in your comments, thoughts and suggestions for new articles, so please feel free to share.

GeoModel and geomodel-demo open sourced

Google Earth API support engineer Roman Nurrik recently open sourced his GeoModel project. GeoModel uses geohash-like objects called 'geocells' to provide a generalized solution for indexing and querying geospatial data in App Engine. GeoModel is optimized for the basic real estate finder/store locator use case, but can be adapted for use with large datasets.

Using GeoModel, developers can instantly geo-contextualize datastore models by simply inherting from the GeoModel class. Currently, entities can be associated with a single geographic point and subsequently indexed and filtered by either conformance to a bounding box or by proximity (nearest-n) to a search center point.

Other open source developments

  • GaeVFS: an Apache Commons VFS plugin which implements a virtual file system on top of the App Engine datastore, using the datastore and memcache APIs.
  • GraniteDS 2.0, now with support for App Engine for Java: Granite DS is an open source alternative to Adobe Lifecycle Data Services for Java EE application servers, and supports both server push and the persistence mechanism on App Engine for Java. For more information about the project and a link to a sample implementation, see the announcement post.
  • jiql: a JDBC-based wrapper of App Engine's low-level datastore API which provides distributed database access via an interface familiar to many developers.
  • pQg: a proof-of-concept PHP-based SQL to JDO wrapper plus sample application.

Java is a trademark or registered trademark of Sun Microsystems, Inc. in the United States and other countries.