The Python Oracle

StructuredProperty inside another StructuredProperty. How to?

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Cool Puzzler LoFi

--

Chapters
00:00 Question
01:08 Accepted answer (Score 8)
01:52 Answer 2 (Score 3)
02:45 Thank you

--

Full question
https://stackoverflow.com/questions/2160...

Accepted answer links:
https://developers.google.com/appengine/...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #googleappengine #googleclouddatastore

#avk47



ACCEPTED ANSWER

Score 8


Although a StructuredProperty can be repeated and a StructuredProperty can contain another StructuredProperty, beware: if one structured property contains another, only one of them can be repeated. A work-around is to use LocalStructuredProperty, which does not have this constraint (but does not allow queries on its property values).

https://developers.google.com/appengine/docs/python/ndb/properties#structured

With LocalStructuredProperty you will have the same structure, but you will not be able to filter by this properties. If you really need to do queries by one of this properties -- try put it into another entity.




ANSWER 2

Score 3


You can't put a repeated StructuredProperty inside another repeated StructuredProperty.

You should use another type of relationship (association, ancestors, etc). For example:

class Property(ndb.Model):
    name    = ndb.StringProperty()
    cost    = ndb.FloatProperty()
    type    = ndb.StringProperty()

class SpecialProperty(ndb.Model):
    hotel      = ndb.KeyProperty(Hotel)
    name       = ndb.StringProperty()
    properties = ndb.StructuredProperty(Property, repeated=True)
    type       = ndb.StringProperty() 

class Hotel(ndb.Model):
    # ... hotel properties

Other option: If you need transactions, you can make Hotel parent of SpecialProperty and Property.

Other option: if you don't need to query on Property, you can store it in a JSONProperty.