3

У меня есть интересная проблема, которая появилась только после обновления моего кода для использования NDB.AppEngine/Python NDB key order

Я использую gae-sessions, который кодирует время истечения сеанса в ключ каждого сеанса, который хранится в базе данных. Например, ключ имеет следующий формат: 1363968220_6ea52c936f16fc557c0c03a5f276a056, где первые 10 символов представляют временную метку времени окончания сеанса (значение 1363968220 кодирует «2013-03-22 16:03:40»).

Перед обновлением до NDB код для удаления истекших сеансов работал правильно. После обновления код ошибочно исключает сеансы, срок действия которых не истек. Код следующий:

time_time = time.time() 
now_str = unicode(int(time_time)) 
now_str_datetime = datetime.datetime.fromtimestamp(time_time) 
q = SessionModel.query(namespace='') 
key = ndb.Key(SessionModel, now_str + u'\ufffd', namespace='') 
logging.info("Deleting sessions with key values less than %s [%s]" % (key, now_str_datetime)) 
q.filter(SessionModel._key < key) 
results = q.fetch(500, keys_only=True) 
# This is for debugging purposes 
for r_key in results: 
    logging.warning("Deleting key %s" % (r_key)) 

Это приводит следующий вывод:

Deleting sessions with key values less than Key('SessionModel', '1363362698\xef\xbf\xbd') [2013-03-15 15:51:38.767947] 
Deleting key Key('SessionModel', '1363924467_e0240e38b4047ef821ac62e07466351b') 

Если эти ключи обрабатываются как строки (используя строку упорядочения правил/приоритета), то ключ, который будет удален (начиная с 1363924467) должно быть не считаться меньше ключа, от которого мы фильтруемся (начиная с 1363362698), и поэтому я смущен тем, что происходит в NDB, что может привести к неправильной работе.

ответ

2

Это трудно объяснить, на основе документа

https://developers.google.com/appengine/docs/python/ndb/keyclass?hl=zh-tw

ключи поддержки сравнений, например ключом1 == key2 или key1 < key2. Эти операторы сравнивают идентификатор приложения, пространство имен и полный путь «предка» . Они используют тот же порядок, что и Datastore для запросов при заказе по ключевому свойству или по ключу.

шпаргалку https://docs.google.com/document/d/1AefylbadN456_Z7BZOpZEXDq8cR8LYu7QgI7bt5V0Iw/mobilebasic

и исходный код. все показывают, что использование должно быть в порядке. Ключ compair app_id, namesapce и пары ключей в порядке. Возможно, вы можете попробовать распечатать (key.app(), key.namespace(), key.pairs()), чтобы просмотреть подробности.

https://code.google.com/p/appengine-ndb-experiment/source/browse/ndb/key.py

def __gt__(self, other): 
    """Greater than ordering.""" 
    if not isinstance(other, Key): 
     return NotImplemented 
    return self.__tuple() > other.__tuple() 

def __tuple(self): 
    """Helper to return an orderable tuple.""" 
    return (self.app(), self.namespace(), self.pairs()) 
Смежные вопросы