Google App Engine Назначение групп объектов / родительских ключей, уникальное ограничение
У меня есть вид "клиента". Я хочу выполнить транзакцию, которая блокирует весь тип, когда собирается вставить нового "Клиента". Транзакция сначала запросит, чтобы проверить, что нового Имени "Клиента" еще не существует, затем вторая часть транзакции выполняет вставку, если совпадений не найдено. Таким образом, я применяю уникальное ограничение (а также ограничиваю операцию до 1 вставки в секунду).
Мое неудовлетворительное решение для получения всех моих сущностей "Клиенты" в одной и той же группе сущностей заключается в создании вида под названием "EntityGroups" с единственной записью "CustomersGroup". Эта одна запись используется каждый раз как Родитель вновь созданных сущностей "Клиент", тем самым группируя весь Вид в одну группу сущностей.
У меня вопрос: меня беспокоит использование фантомной записи, такой как "CustomerGroup", потому что, если что-то произошло, и оно было потеряно или удалено, я не мог бы назначить новые сущности "Клиент" в ту же группу! Я полагаю, что было бы лучше назначить Родителем каждого объекта "Клиент" статического произвольного родителя, такого как "1111111"? Я думаю, что терминология "виртуальный корневой объект", как мне это сделать?
Пожалуйста, помогите с любым советом о том, как я могу лучше всего справиться с этим!
4 ответа
Почему бы вам не использовать: get_or_insert NDB: Транзакционно извлекает существующую сущность или создает новую.
https://developers.google.com/appengine/docs/python/ndb/modelclass
Ваш CustomerGroup
запись не должна существовать, чтобы она выступала в роли родителя. Просто создайте ключ вручную и назначьте его в качестве родителя для рассматриваемой записи.
Вам не нужно беспокоиться об удалении, если оно не существует!
Когда вы создаете модель и устанавливаете другую в качестве родительской, система не проверяет (и не нуждается) в том, что эта модель вообще существует.
Так, например:
rev_key = ndb.Key('CustomerGroup', '11111', 'Customer', 'New_Customer_Name')
Еще модель с ключом: ('CustomerGroup', '11111')
на самом деле не существует, но все еще может быть в цепочке предков.
GrantsV, вы можете достичь этого, создав прокси-объект для каждого уникального ограничения и используя межгрупповые транзакции для фиксации ограничений с обычными записями.
class UniqueConstraint(db.Model):
# Consider adding a reference to the owner of the constraint.
@db.transactional(propagation=db.MANDATORY, xg=True)
@classmethod
def reserve(cls, kind, property, value):
key = cls.__get_key(kind, property, value)
if db.get(key):
raise Exception # Already exists
cls(key=key).put()
@db.transactional(propagation=db.MANDATORY, xg=True)
@classmethod
def release(cls, kind, property, value):
db.delete(cls.__get_key(kind, property, value))
@classmethod
def __get_key(cls, kind, property, value):
# Consider using a larger entity group.
return db.Key.from_path(cls.kind(), '%s:%s:%s' % (kind, property, value))
# To restrict to 1 insert per second per kind, use:
# return db.Key.from_path(cls.kind(), kind, cls.kind(), '%s:%s' % (property, value))
Вы можете создать родительский объект, например так:
class CustomerParent(ndb.Model):
pass
Затем вы создаете и сохраняете свою родительскую сущность:
customers_parent = CustomerParent()
customers_parent.put()
Наконец, когда вы создаете все свои объекты клиентов, вы указываете родителя:
a_customer = Customer(parent=customers_parent.key, ...)
a_customer.put()
Надеюсь это поможет!