def create_multi(cls, values): """Creates multiple unique values at once. :param values: A sequence of values to be unique. See :meth:`create`. :returns: A tuple (bool, list_of_keys). If all values were created, bool is True and list_of_keys is empty. If one or more values weren't created, bool is False and the list contains all the values that already existed in datastore during the creation attempt. """ # Maybe do a preliminary check, before going for transactions? # entities = model.get_multi(keys) # existing = [entity.key.id() for entity in entities if entity] # if existing: # return False, existing # Create all records transactionally. keys = [model.Key(cls, value) for value in values] entities = [cls(key=key) for key in keys] func = lambda e: e.put() if not e.key.get() else None created = [model.transaction(lambda: func(e)) for e in entities] if created != keys: # A poor man's "rollback": delete all recently created records. model.delete_multi(k for k in created if k) return False, [k.id() for k in keys if k not in created] return True, []
def get(self, name): NOT_SET_VALUE = u'!!!__ NOT SET __!!!' entity = self(key=model.Key(self, name)) entity.populate(value=NOT_SET_VALUE) txn = lambda: entity.put() if not entity.key.get() else entity.key retval = model.transaction(txn).get() # Fall back to environment vars if retval.value == NOT_SET_VALUE: fallback_value = environ.get(name) if fallback_value is not None: retval.value = fallback_value retval.put() return fallback_value if retval.value == NOT_SET_VALUE: logging.error( ('%s %s not found in the database. A placeholder ' + 'record has been created. Go to the Developers Console ' 'for your app in App Engine, look up the Settings record ' 'with name=%s and enter its value in that record\'s value ' 'field.') % (self.__name__, name, name)) return retval.value
def create(cls, value): """Creates a new unique value. :param value: The value to be unique, as a string. The value should include the scope in which the value must be unique (ancestor, namespace, kind and/or property name). For example, for a unique property `email` from kind `User`, the value can be `User.email:[email protected]`. In this case `User.email` is the scope, and `[email protected]` is the value to be unique. :returns: True if the unique value was created, False otherwise. """ entity = cls(key=model.Key(cls, value)) txn = lambda: entity.put() if not entity.key.get() else None return model.transaction(txn) is not None
def get(cls, name): # Unique canary value (`None` may be a valid value for this config item) NOT_SET_VALUE = u'!!!__ NOT SET __!!!' # Need to ensure uniqueness in a transaction entity = cls(key=model.Key(cls, name)) entity.populate(value=NOT_SET_VALUE) txn = lambda: entity.put() if not entity.key.get() else entity.key retval = model.transaction(txn).get() if retval.value == NOT_SET_VALUE: raise Exception(( '%s %s not found in the database. A placeholder ' + 'record has been created. Go to the Developers Console for your app ' + 'in App Engine, look up the Settings record with name=%s and enter ' + 'its value in that record\'s value field. ') % (cls.__name__, name, name)) return retval.value