Python newbie question, getting the datetime out of a DateTimeProperty

671 views
Skip to first unread message

Ben H.

unread,
May 3, 2008, 8:25:53 PM5/3/08
to Google App Engine
I figure I'm not the only person new to python trying GAE, so here's
my question. I tried nutting this out for a couple of hours, but it
stopped being fun, so I thought I'd ask.

I'm querying a bunch of models which have a timestamp recorded in a
DateTimeProperty. I want to compare this to the current moment in
order to work out how old they are, and display some human-friendly
age indication (like gmail does).

Problem is I can't figure out how to get the inner datetime out of the
DateTimeProperty so that I can subtract it from
DateTimeProperty.now(), which returns a datetime. I've tried looking
at the datastore code but can't make head nor tail of it, but I figure
there must be some implicit voodoo going on that allows these dates to
be printed just fine (__str__), but I actually want to do stuff with
the datetime inside the DateTimeProperty - how do I get it out?

The minus operator does not work on a DateTimeProperty and a datetime.

thanks and apologies in advance for what I am sure will be obvious in
retrospect,
b

Duncan

unread,
May 4, 2008, 6:22:25 AM5/4/08
to Google App Engine
You don't have to do anything special to access a DateTimeProperty,
the value of the property is a datetime object and if you subtract two
datetime objects you'll get a timedelta object. e.g. Here's some
simple code which demonstrates that (and which can be run with
doctest)

>>> from datetime import datetime, timedelta
>>> from google.appengine.ext import db
>>> class Test(db.Model):
... date = db.DateTimeProperty(auto_now_add=True)
... date2 = db.DateTimeProperty()

>>> obj = Test(date2=datetime(2008,1,1))
>>> obj.date - datetime.now() < timedelta(1)
True
>>> obj.date2 == datetime(2008,1,1)
True
>>> obj.date2.strftime("%a, %d %b %Y %H:%M:%S +0000")
'Tue, 01 Jan 2008 00:00:00 +0000'

If you are having problems try cutting your code down to something
minimal involving the properties which doesn't do what you expect and
post the code.

Con

unread,
May 4, 2008, 4:25:32 PM5/4/08
to Google App Engine
Hey Duncan, how does one properly add the search path to the
environment so that I can
try the example below?

Thanks in advance,

-Conrad

Con

unread,
May 4, 2008, 5:02:00 PM5/4/08
to Google App Engine
Hey Duncan, I got the above example working as expected. However, it
appears that I'm missing some paths when I attempt to import the
greetings application. Just trying to get my hands wrapped around
Python and GAE. Is there way to invoke the Python interpreter so that
it automatically loads the current GAE?

-Conrad

Duncan

unread,
May 4, 2008, 5:09:26 PM5/4/08
to Google App Engine
On May 4, 9:25 pm, Con <conra...@gmail.com> wrote:
> Hey Duncan, how does one properly add the search path to the
> environment so that I can
> try the example below?

Try this (if your projects is in folder X then put this in test/
runtests.py). If you aren't running on Windows then GOOGLE_PATH will
need changing.
It will run any doctests in .py files in the main folder, and also any
text files with an extension .tests in the tests sub-folder.

-------------------------------------------------------------
import os, sys, glob
import unittest
import doctest
from os.path import dirname, basename, splitext, join

TESTDIR = dirname(__file__)
MAINDIR = dirname(TESTDIR)

GOOGLE_PATH = "C:/Program Files/Google/google_appengine"

EXTRA_PATHS = [
TESTDIR,
MAINDIR,
GOOGLE_PATH,
os.path.join(GOOGLE_PATH, 'lib', 'django'),
os.path.join(GOOGLE_PATH, 'lib', 'webob'),
os.path.join(GOOGLE_PATH, 'lib', 'yaml', 'lib'),
]
for directory in EXTRA_PATHS:
if not directory in sys.path:
sys.path.insert(0, directory)

from google.appengine.api import apiproxy_stub_map
from google.appengine.api import datastore_file_stub
from google.appengine.api import mail_stub
from google.appengine.api import urlfetch_stub
from google.appengine.api import user_service_stub

APP_ID = u'test_app'
AUTH_DOMAIN = 'gmail.com'
LOGGED_IN_USER = 'te...@example.com' # set to '' for no logged in
user

def setUp(self):
# Start with a fresh api proxy.
apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()

# Use a fresh stub datastore.
stub = datastore_file_stub.DatastoreFileStub(APP_ID, '/dev/null', '/
dev/null')
apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', stub)

# Use a fresh stub UserService.
apiproxy_stub_map.apiproxy.RegisterStub('user',
user_service_stub.UserServiceStub())
os.environ['AUTH_DOMAIN'] = AUTH_DOMAIN
os.environ['USER_EMAIL'] = LOGGED_IN_USER

# Use a fresh urlfetch stub.
apiproxy_stub_map.apiproxy.RegisterStub(
'urlfetch', urlfetch_stub.URLFetchServiceStub())

# Use a fresh mail stub.
apiproxy_stub_map.apiproxy.RegisterStub(
'mail', mail_stub.MailServiceStub())

def initGlobs():
"""Create global variables for use in tests."""
return {}

def getModules():
"""return all modules in the parent directory"""

modules = [ splitext(basename(name))[0] for name in
glob.glob(join(MAINDIR, '*.py'))]
for mod in modules:
if not mod.startswith('_'):
yield __import__(mod)

def getDocTests():
"""Find doctest files in current directory"""
return glob.glob(join(TESTDIR, '*.tests'))


if __name__=='__main__':
suite = unittest.TestSuite()
for name in getDocTests():
suite.addTest(doctest.DocFileSuite(name,
module_relative=False))
for mod in getModules():
try:
suite.addTest(doctest.DocTestSuite(mod,
extraglobs=initGlobs(), setUp=setUp))
except ValueError, e:
print >>sys.stderr, e
runner = unittest.TextTestRunner()
runner.run(suite)
-----------------------------------------------------------------

Duncan

unread,
May 5, 2008, 5:44:12 AM5/5/08
to Google App Engine
In case the email got too messed about, I've uploaded an entire test
project as a zip file and written a brief description about using it
to run doctests.

See http://kupuguy.blogspot.com/:
> The App Engine isn't too friendly for testing: you can't use
> interactive mode, and there's some setup needed to get a test harness.
>
> I've found that using doctest works quite nicely with the appengine,
> provided you get that initial setup out of the way. If your
> application interacts with the datastore, then you probably want to
> set up some objects before querying them and to my mind that sits
> better with the doctest model of a long chatty document describing a
> pseudo-interactive session than the xUnit style of separate tests each
> starting from a clean system doing something and making a single
> assertion about the resulting state. For a particular project you can
> update the test framework to perform common setup for the tests.

Aral Balkan

unread,
Jun 12, 2008, 7:51:15 PM6/12/08
to Google App Engine
Hey Duncan,

This rocks, thanks so much.

> > The App Engine isn't too friendly for testing: you can't use
> > interactive mode, and there's some setup needed to get a test harness.

With django-based projects, I'm finding the Django shell very
useful: ./manage.py shell

Aral

Reply all
Reply to author
Forward
0 new messages