Use db.StringProperty () as a unique identifier in the Google App Engine

I have a hunch. But if it seems to me that I am doing it wrong. I want db.StringProperty () to be a unique identifier. I have a simple db.Model with name and file. If I add another entry with the same name as in db.Model, I want to update this.

As far as I know, I look:

template = Templates.all().filter('name = ', name) 

Check if there is another entry:

 if template.count() > 0: 

Then add it or update. But from what I read .count () is expensive to use the CPU.

Is it possible to set the "name" property as unique, and the data store will automatically update it or another best way to do this?

.. Fredrick

+2
source share
6 answers

You cannot make a property unique in the App Engine datastore. Instead, you can specify a key name for your model, which is guaranteed to be unique - see docs for more details.

+2
source

I had the same problem and the following answer was given as simplest:

 class Car(db.Model): name = db.StringProperty(required=True) def __init__(self,*args, **kwargs): super(Car, self).__init__(*args, **kwargs) loadingAnExistingCar = ("key" in kwargs.keys() or "key_name" in kwargs.keys()) if not loadingAnExistingCar: self.__makeSureTheCarsNameIsUnique(kwargs['name']) def __makeSureTheCarsNameIsUnique(self, name): existingCarWithTheSameName = Car.GetByName(name) if existingCarWithTheSameName: raise UniqueConstraintValidationException("Car should be unique by name") @staticmethod def GetByName(name): return Car.all().filter("name", name).get() 

The important thing is not to first check if we are loading an existing object.

For a complete solution: http://nicholaslemay.blogspot.com/2010/07/app-engine-unique-constraint.html

+2
source

You can just try to get your essence and edit it, and if you don’t find it, create a new one:

 template = Templates.gql('WHERE name = :1', name) if template is None: template = Templates() # do your thing to set the entity properties template.put() 

Thus, it will insert a new record if it was not found, and if it is found, it will update the existing record with the changes you made (see the documentation here ).

+1
source

An alternative solution is to create a model to store unique values ​​and save it transactionally, using the combination Model.property_name.value as a key. Only if this value is created do you save your actual model. This solution is described here (with code):

http://squeeville.com/2009/01/30/add-a-unique-constraint-to-google-app-engine/

+1
source

I agree with Nick. But, if you ever want to check the existence of a model / entity based on a property, the get () method is convenient:

 template = Templates.all().filter('name = ', name).get() if template is None: # doesn't exist else: # exists 
0
source

I wrote the code for this. The idea behind this is that it is very easy to use. So you can do this:

 if register_property_value('User', 'username', 'sexy_bbw_vixen'): return 'Successfully registered sexy_bbw_vixen as your username!' else: return 'The username sexy_bbw_vixen is already in use.' 

This is the code. There are many comments, but in fact these are just a few lines:

 # This entity type is a registry. It doesn't hold any data, but # each entity is keyed to an Entity_type-Property_name-Property-value # this allows for a transaction to 'register' a property value. It returns # 'False' if the property value is already in use, and thus cannot be used # again. Or 'True' if the property value was not in use and was successfully # 'registered' class M_Property_Value_Register(db.Expando): pass # This is the transaction. It returns 'False' if the value is already # in use, or 'True' if the property value was successfully registered. def _register_property_value_txn(in_key_name): entity = M_Property_Value_Register.get_by_key_name(in_key_name) if entity is not None: return False entity = M_Property_Value_Register(key_name=in_key_name) entity.put() return True # This is the function that is called by your code, it constructs a key value # from your Model-Property-Property-value trio and then runs a transaction # that attempts to register the new property value. It returns 'True' if the # value was successfully registered. Or 'False' if the value was already in use. def register_property_value(model_name, property_name, property_value): key_name = model_name + '_' + property_name + '_' + property_value return db.run_in_transaction(_register_property_value_txn, key_name ) 
0
source

Source: https://habr.com/ru/post/1311945/


All Articles