2

I have the following python module:

from google.appengine.ext import db
from user import User

class Post(db.Model):
    content = db.TextProperty()
    time = db.DateTimeProperty(auto_now_add=True)
    user = db.ReferenceProperty(User)
    topic = db.ReferenceProperty(Topic)

class Forum(db.Model):
    parent_ = db.SelfReferenceProperty()
    name = db.StringProperty()
    description = db.StringProperty()
    topics_count = db.IntegerProperty(default=0)
    posts_count = db.IntegerProperty(default=0)
    last_post = db.ReferenceProperty(Post)


class Topic(db.Model):
    forum = db.ReferenceProperty(Forum)
    title = db.StringProperty()
    replies_count = db.IntegerProperty(default=0)
    views = db.IntegerProperty(default=0)
    time = db.DateTimeProperty(auto_now_add=True)
    user = db.ReferenceProperty(User)
    last_post = db.ReferenceProperty(Post)

This does not work because I use Topic in Post class. I read this solution and solved the circular dependency problem. The resulting module is as follows:

from google.appengine.ext import db
from user import User

class Post(db.Model):
    content = db.TextProperty()
    time = db.DateTimeProperty(auto_now_add=True)
    user = db.ReferenceProperty(User)


class Forum(db.Model):
    parent_ = db.SelfReferenceProperty()
    name = db.StringProperty()
    description = db.StringProperty()
    topics_count = db.IntegerProperty(default=0)
    posts_count = db.IntegerProperty(default=0)
    last_post = db.ReferenceProperty(Post)


class Topic(db.Model):
    forum = db.ReferenceProperty(Forum)
    title = db.StringProperty()
    replies_count = db.IntegerProperty(default=0)
    views = db.IntegerProperty(default=0)
    time = db.DateTimeProperty(auto_now_add=True)
    user = db.ReferenceProperty(User)
    last_post = db.ReferenceProperty(Post)


Post.topic = db.ReferenceProperty(Topic)

However now I have another problem. App Engine creates Post table, but it does not have topic column. How can I solve this problem?

Community
  • 1
  • 1
ipman
  • 1,212
  • 2
  • 21
  • 29
  • 2
    It's good to define the referenced class, but you don't have to. topic = db.ReferenceProperty() will do unless you need to specify it. – Bugs Oct 27 '12 at 20:04
  • If I do topic = db.ReferenceProperty(), I get the following error: DuplicatePropertyError: Class User already has property post_set – ipman Oct 27 '12 at 20:12
  • 1
    Read about collection_name [in the docs](https://developers.google.com/appengine/docs/python/datastore/typesandpropertyclasses#ReferenceProperty). – Bugs Oct 27 '12 at 20:14

1 Answers1

2

This approach will not work properly, because db.Model has a metaclass which does initialization work on the list of db properties at the time the class is created. Since your property was not there at that time, the necessary initialization will not be applied to it.

You might want to consider switching to NDB, which supports circular references by using a string name for one of the key properties.

Nick Johnson
  • 100,655
  • 16
  • 128
  • 198