0
votes

I run into some problems trying to create entities using this structure:

class MainEnt(ndb.Model):
    name = ndb.StringProperty()
    choices = ndb.KeyProperty(repated=True)

    @classmethod
    @ndb.transactional
    def create(cls, name, choices):
        #Here comes my problem!

class Choice(ndb.Model):
    name = ndb.StringProperty()

So here I have a main entity that haves a list of some choices. To create the main entity I need to use a transaction to consistently create the main entity and the choices entities. If some operation fail I want all to fail.

The problem is that to run inside a transaction all need to be in the same entity group but I can't do that because I don't know the key of the main entity to assign it as the parent argument to each choice. I can't use allocate_ids inside a transaction so this option doesn't work.

I don't want to use Cross-Group transactions, and also don't want to save the main entity two times.

Also I was considering using queries to fetch the choices and don't use the repeated property, but as long as I will usually only have 2-3 choices per MainEnt, using queries is a waste of resources.

What can I do?

1
Are you trying to create all the Choice entities at the same time and store their keys in the choices property ? Surely all MainEnt's would refer to the shared set of Choice entities. I suggest you show what code you are running inside your create factory so we can see what you are really up to.Tim Hoffman
If instances of the choice entity are owned by MainEnt then you could just create them as children and drop the repeated KeyProperty.Tim Hoffman
The code inside create is what i'm looking for... Maybe something like: create the MainEnt and put it, then create the choices and put them, and then modify choices property in MainEnt with the keys of the Choices created later. Here as you see. I put 2 times MainEnt. I'm looking for a formula to do this writting to the datastore only 2 times.janscas
So are instances of choices shared with all MainEnt instances or exclusive to a single instance of MainEnt?Tim Hoffman
No, Choices are not shared. Each one is unique to its MainEnt.janscas

1 Answers

2
votes

If you are going to fetch all Choices every time then just use a repeated StructuredProperty

class Choice(ndb.Model):
    name = ndb.StringProperty()

class MainEnt(ndb.Model):
    name = ndb.StringProperty()
    choices = ndb.StructuredProperty(Choice,repeated=True)

    def create(cls, name, choices):
       m = cls.MainEnt(name=name)
       m.choices = [Choice(name=name) for name in choices]
       m.put()