Используйте db.StringProperty () в качестве уникального идентификатора в Google App Engine. - PullRequest
2 голосов
/ 10 февраля 2010

У меня есть догадка об этом.Но если мне кажется, что я делаю это неправильно.Что я хочу сделать, это иметь db.StringProperty () в качестве уникального идентификатора.У меня есть простая модель db.Model с именем свойства и файлом.Если я добавлю еще одну запись с тем же «именем», что и в db.Model, я хочу ее обновить.

Насколько мне известно, я смотрю его с помощью:

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

Проверьте, уже одна ли это запись:

if template.count() > 0:

Затем добавьте или обновите ее.Но из того, что я прочитал, .count () обходится очень дорого в использовании ЦП.

Есть ли возможность установить свойство "name" уникальным, и хранилище данных автоматически обновит его или другой лучший способ сделать это?это?

.. Фредрик

Ответы [ 6 ]

2 голосов
/ 21 июля 2010

У меня была та же проблема, и я нашел следующий ответ, как самый простой:

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()

Важно, чтобы я сначала не проверял, загружаем ли мы сначала существующую сущность.

Для полного решения: http://nicholaslemay.blogspot.com/2010/07/app-engine-unique-constraint.html

2 голосов
/ 10 февраля 2010

Невозможно сделать свойство уникальным в хранилище данных App Engine. Вместо этого вы можете указать ключевое имя для вашей модели, которое гарантированно будет уникальным - подробнее см. документы .

1 голос
/ 11 августа 2011

Альтернативное решение заключается в создании модели для хранения уникальных значений и ее транснационального хранения с использованием комбинации Model.property_name.value в качестве ключа.Только если это значение создано, вы сохраняете фактическую модель.Это решение описано (с кодом) здесь:

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

1 голос
/ 10 февраля 2010

Вы можете просто попытаться получить свою сущность и отредактировать ее, и если она не найдена, создайте новую:

template = Templates.gql('WHERE name = :1', name)
if template is None:
  template = Templates()

# do your thing to set the entity's properties

template.put()

Таким образом он вставит новую запись, когда она не была найдена, и, если она была найдена, обновит существующую запись с внесенными изменениями (см. Документацию здесь ).

0 голосов
/ 10 июня 2012

Я написал некоторый код для этого. Идея в том, чтобы быть довольно простым в использовании. Таким образом, вы можете сделать это:

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 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 голосов
/ 10 февраля 2010

Я согласен с Ником. Но, если вы когда-нибудь захотите проверить существование модели / сущности на основе свойства, метод get () пригодится:

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