开发者

GAE Models: How to list child nodes in parent

开发者 https://www.devze.com 2023-03-11 10:10 出处:网络
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 her

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

精彩评论

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

关注公众号