-1

Is there an alternative way/strategy which could be used to achieve the same as provided "transaction" in GAE Python?
In GAE, "Transaction" helps ensure that all the NDB operations inside a transaction succeed or all are rolled back.
I cannot use "transaction" at many places in my code, where I feel it is needed, due to the entity group count limit of 5(xg).
Appreciate your time.

One of the use cases

class A(ndb.Model): 
    :: # Some Properties 

class B(ndb.Model): 
    :: # Some Properties 

class C(ndb.Model): 
    :: # Some Properties 

class D(ndb.Model): 
    :: # Some Properties 

class E(ndb.Model): 
    :: # Some Properties 

class F(ndb.Model): 
    :: # Some Properties

class G(ndb.Model): 
    :: # Some Properties 

class create_new_x (BaseRequestHandler): 
    @ndb.toplevel 
    def get(self): 
        :: 
        a1 = A (id="x", p1=v1, .. , pn=vn) 
        a1.put_async () 

        b1 = B (id="y", p1=v1, .. , pn=vn) 
        b1.put_async () 

        :: 
        g1 = G (id="z", p1=v1, .. , pn=vn) 
        g1.put_async () 

        return 

When I create a new entity (say, "A1") of Model "A", I also create entities (say, "B1", "C1", D1", "E1", "F1", "G1") of Models "B", "C", "D", "E", "F", "G" in the same user request. I do not want to assign a parent for entities "B1", "C1", D1", "E1", "F1", "G1". If I assign them parent (as "A1"), then I would have to first get "A1" whenever I want to get any of "B1", "C1", D1", "E1", "F1", "G1". This is because we need to specify the ancestor key in "get_by_id".

Dan McGrath
  • 41,220
  • 11
  • 99
  • 130
gsinha
  • 1,165
  • 2
  • 18
  • 43
  • 1
    I'm guessing it's because your question is very broad and any recommendations would have to be specific to your implementation. Code samples are helpful. – user3058197 Jul 20 '14 at 19:47
  • @user3058197 Thanks for trying to help. I have updated the question with more information. I have added analogous example of one such part of my code. – gsinha Jul 20 '14 at 20:13
  • 1
    if you create the parent model with a specified key you can use that (construct a key manually) as the parent in get_by_id without actually retrieving it. It does not even have to exist for it to be used like that. – Paul Collingwood Jul 21 '14 at 12:40
  • @PaulCollingwood That sounds like a good solution to the problem. Thanks for your help. You also mentioned: `It does not even have to exist for it to be used like that.` Do you mean to say that the key used to create the entities could be fake (not being the key for any entity at all but simply created using an id)? Please add your suggestion as an answer so that I could accept it. – gsinha Jul 21 '14 at 17:23

1 Answers1

1

You can retrieve an entity by constructing a key by hand, including the ancestor path:

rev_key = ndb.Key('Account', 'Sandy', 'Message', 'greeting', 'Revision', '2')
address = ndb.get(rev_key)

You can also use the named parameter parent to designate any entity in the ancestor path directly.

k2 = ndb.Key(Revision, '2', parent=ndb.Key('Account', 'Sandy', 'Message', 'greetings'))

The parent in the chain does not have to exist for it to be used in this way, however typically you'd create it (e.g. an author as the parent with books as children) as part of the setup. But if it's name can be determined in advance you can use it.

You can filter your Datastore queries to a specified ancestor, so that the results returned will include only entities descended from that ancestor

https://developers.google.com/appengine/docs/python/ndb/entities

Google Appengine NDB ancestor vs key query

Community
  • 1
  • 1
Paul Collingwood
  • 9,053
  • 3
  • 23
  • 36