Глупый, но быстрый подход состоит в том, чтобы взять поля, которые вас интересуют, объединить их в виде длинной строки и сохранить их как ключ сущности DB_Unique
, которая ссылается на исходную сущность. Каждый раз, когда вы делаете DB_Unique.get_or_insert()
, вы должны проверять ссылку на правильный исходный объект, в противном случае у вас есть дубликат. Это, вероятно, должно быть сделано в карте уменьшения .
Что-то вроде:
class DB_Unique(db.Model):
r = db.ReferenceProperty()
class DB_Obj(db.Model):
a = db.IntegerProperty()
b = db.StringProperty()
c = db.StringProperty()
# executed for each DB_Obj...
def mapreduce(entity):
key = '%s_%s_%s' % (entity.a,entity.b,entity.c)
res = DB_Unique.get_or_insert(key, r=entity)
if DB_Unique.r.get_value_for_datastore(res) != entity.key():
# we have a possible collision, verify and delete?
# out two entities are res and entity
Есть несколько крайних случаев, которые могут всползти, например, если у вас есть две сущности с b и c, равными ('a_b', '') и ('a', 'b_') соответственно, поэтому конкатенация 'a_b_' для обоих. поэтому используйте символ, который, как вы знаете, отсутствует в ваших строках, вместо '_', или укажите DB_Unique.r
в качестве списка ссылок и сравните их все.