momijigari
momijigari

Reputation: 1598

How to check the existance of single Entity? Google App Engine, Python

Sorry for noobster question again.

But I'm trying to do some very easy stuff here, and I don't know how. Documentation gives me hints which do not work, or apply.

I recieve a POST request and grab a variable out of it. It says "name".

I have to search all over my entities Object (for example) and find out if there's one that has the same name. Is there's none, I must create a new Entity with this name. Easy it may look, but I keep Failing. Would really appreciate any help.

My code currently is this one:

 objects_qry = Object.query(Object.name == data["name"])

        if (not objects_qry ):
            obj = Object()
            obj .name =  data["name"]
            obj .put()

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

Upvotes: 0

Views: 1038

Answers (2)

Tim Hoffman
Tim Hoffman

Reputation: 12986

Using a query to perform this operation is really inefficient.

In addition your code is possibly unreliable, if name doesn't exist and you have two requests at the same time for name you could end up with two records. And you can't tell because your query only returns the first entity with the name property equal to some value.

Because you expect only one entity for name a query is expensive and inefficient. So you have two choices you can use get_or_insert or just do a get, and if you have now value create a new entity.

Any way here is a couple of code samples using the name as part of the key.

name = data['name']
entity = Object.get_or_insert(name) 

or

entity = Object.get_by_id(name)
if not entity:
    entity = Object(id=name)
    entity.put()

Upvotes: 5

Greg
Greg

Reputation: 10360

Calling .query just creates a query object, it doesn't execute it, so trying to evaluate is as a boolean is wrong. Query object have methods, fetch and get that, respectively, return a list of matching entities, or just one entity.

So your code could be re-written:

objects_qry = Object.query(Object.name == data["name"])
existing_object = objects_qry.get()

if not existing_object:
  obj = Object()
  obj.name = data["name"]
  obj.put()

That said, Tim's point in the comments about using the ID instead of a property makes sense if you really care about names being unique - the code above wouldn't stop two simultaneous requests from creating entities with the same name.

Upvotes: 2

Related Questions