开发者

GAE Models: How to list child nodes in parent

Using Google App Engine in Python and references, you automatically get a back reference from the referenced object to the one you're dealing with. This is described very well in the answer found here.

What I'd like to do is create a (simpler) one-to-many relationship, with each Group having a list of Tags, and each Tag belongs to only one Group. I picture it something like the following:

class Group(db.Model):
    # All of my group-specific data here.

class Tag(db.Model):
    text = db.StringProperty(required=True)
    group = db.ReferenceProperty(Group, collection='tags')

Assuming I understand everything correctly... In the above, you wind up with each Group having a tags property:

# Get the list of Tag objects that belong to a Group object
mytags = mygroup.tags 

My question is, is there a "standard" way to include that information in the Group object? When looking at the data models, you can't see by looking at the Group object that it has a list of Tags that apply to it. I'd like to be able to define Group,Tags as something like

class Group(db.Model):
    # This should automatically be the same as the "tags" property that is
    # created for the Group开发者_StackOverflow中文版 model by the definition of the Tag model
    tags = db.ListProperty(db.Key)
    # All of my group-specific data here.

class Tag(db.Model):
    text = db.StringProperty(required=True)
    group = db.ReferenceProperty(Group, collection='tags', required=True)
    # Other tag specific information here (such as url, etc)

The idea being that I want to be able to see, when I look at the Group model, that it has a list of Tag objects as a property. It feels unnatural to me to have to look at the Tag model to know this information.

Note: It may be worth noting that I plan on having the Group in question be the parent (for the Entity Group) of each of it's Tags. Any time I modify a Group, I will be updating it completely, replacing all of it's Tags with new ones, and I want to get the correct list of them for the given "version" of the Group I'm looking at.

The use cases for my data include:

  • Update groups - create or update 6 groups. If create, then create the tags for the group. If update, completely replace the tags for the group (removing old ones) - happens every 5 minutes or so
  • Read recent groups - get the 6-20 (undecided yet) most recently modified groups, no need to load their tags
  • Read single group - get the information for a single group, including it's tags (each one will have between 10 and 20 tags)


How are you going to query your tags, will you be concerned only with tags from a particular entity group? If that is the case, since you're going to put your Tag entities in a Group entity's entity group, the ReferenceProperty provides no real value. You could instead use tag_entity.key().parent() to get the Group entity's key or tag_entity.parent() to get the Group entity itself. You could then use a ListProperty on Group to store the key_names of the tag entities (which I presume will be the actual 'tag').

Since you are replacing all of a group's tags any time the Group entity is updated, have you considered using a ListProperty to store your tags on directly on Group entity. Or, storing a list of tag key_names directly on Group. Either approach would make fetching all tags for a group quite easy and efficient.


Having a ListProperty as you suggest will, as you probably realize, mean you're keeping two references redundantly, which isn't necessary. A simpler approach would be to simply note in a comment that describes the relationship.

If you're going to use entity groups anyway, though, you don't need the ReferenceProperty or the ListProperty. You can fetch the Tag children of a Group with Tag.all().ancestor(my_group).

Another option would be to store the tags as a list of strings. Additional information can be stored in Tag entities with key_names set to the tag name. You can then fetch all the tag entities referenced by an object with Tag.get_by_key_name(my_entity.tags). This is mostly useful if you usually only need the tag names and only sometimes retrieve the full data - otherwise you may as well stick with a ReferenceProperty or an Entity Group.


modeling in appengine

one-to-many using parent in that will come in handy for you

you can also consider other examples

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜