ndb put () работает, но не обновляет результат одновременно через 15-30 секунд

У меня очень интересная проблема (для меня точно), у меня есть запрос, и в этом запросе у меня есть строка списка:

class TestList(ndb.Model):
    testing_list = ndb.StringProperty(repeated=True)
    list_id = ndb.IntegerProperty()

Также у меня есть методы API для изменения test_list по запросу PATCH. Код для этого:

@app.route('/list/change', methods=['PATCH'])
def list_change():
    list_id = request.form['id']
    list_elements = request.form['elements']
    query = TestList.query(TestList.list_id == int(list_id))
    try:
        query.fetch()[0].list_id
    except IndexError:
        return 'Error', 400
    new_elements = str(list_elements).replace(' ', '').split(',')
    query.fetch()[0].testing_list = [element for element in new_elements if element in query.fetch()[0].testing_list]
    query.fetch()[0].put()

    testing_list_extend(query.get(), new_elements)
    return 'Success', 200

@ndb.transactional
def testing_list_extend(list_key, new_elements):
    for element in new_elements:
        query = TestList.query(ancestor=list_key.key)
        if element not in query.fetch()[0].testing_list:
            query.fetch()[0].testing_list.append(element)
            query.fetch()[0].put()
    return '200'

На входе я получаю строку как «Element1, Element2», это PATCH в запросе тела и id как «1». Поэтому после того, как я разобрал строку и сделаю список. После того, как я хочу добавить новые уникальные элементы в test_list. В этой части у меня есть ошибка: иногда, когда я добавляю новые элементы и получаю test_list по запросу GET, я получаю пустой список, но за 15-30 секунд я получаю список, который я хотел увидеть некоторое время назад. Например, в запросе тела PATCH:

id = '1'
elements = 'Element1, Element2'

Какой ответ я ожидаю, получив id :

[Element1, Element2]

То, что я получаю очень часто:

[Element1, Element2]

То, что я получаю очень редко (ошибка, как я думаю):

[]
0
задан 13 August 2018 в 14:28

1 ответ

Здесь кое-что не так, но я думаю, что причиной вашей проблемы является многократное использование puts и fetches. Это будет намного лучше, если вы можете использовать клавишу TestList s вместо TestList.list_id. Таким образом, ваша функция будет выглядеть примерно так:

@app.route('/list/change', methods=['PATCH'])
def list_change():
    list_id = request.form['id']
    list_elements = request.form['elements']
    new_elements = str(list_elements).replace(' ', '').split(',')
    try:
        testing_list_extend(ndb.Key(TestList, long(list_id)), new_elements)
        return 'Success', 200
    except Exception as e:
        return e.message, 400

@ndb.transactional
def testing_list_extend(list_key, new_elements):
    test_list = list_key.get()
    if test_list is None:
        raise Exception('Test List ID does not exist')
    l = []
    l.extend(entity.testing_list)  # the existing list
    l.extend(new_elements)  # the append the new_elements
    entity.testing_list = list(set(l))  # remove duplicates
    entity.put()

В противном случае попробуйте сделать это следующим образом:

@app.route('/list/change', methods=['PATCH'])
def list_change():
    list_id = request.form['id']
    list_elements = request.form['elements']
    new_elements = str(list_elements).replace(' ', '').split(',')
    try:
        # Only return the Key, to be used in the transaction below
        query = TestList.query(TestList.list_id == int(list_id)).fetch(2, keys_only=True)
        if len(query) == 0:
            raise Exception("Found no 'TestList' with list_id == %s" % list_id)
        # Double check for duplicates
        elif len(query) == 2:
            raise Exception("Found more than one 'TestList' with list_id == %s" % list_id)
        testing_list_extend(query[0], new_elements)
        return 'Success', 200
    except Exception as e:
        return e.message, 400

@ndb.transactional
def testing_list_extend(list_key, new_elements):  # same
    test_list = list_key.get()
    if test_list is None:
        raise Exception('Test List ID does not exist')
    l = []
    l.extend(entity.testing_list)  # the existing list
    l.extend(new_elements)  # the append the new_elements
    entity.testing_list = list(set(l))  # remove duplicates
    entity.put()
1
ответ дан 15 August 2018 в 17:03
  • 1
    Спасибо, я изменяю свой код! Но проблема заключалась в кэшировании ndb. Я написал функциональный тест для этой проблемы и выяснил, что строка в Datastore в google.cloud была обновлена, но в то же время я сделал запрос GET и получил старую дату, поэтому в моем GET , я положил ndb.get_context().clear_cache(), и он отлично работает. – Ruslan 14 August 2018 в 14:48
  • 2
    @Ruslan Вы могли бы опубликовать это как ответ на благо сообщества? – Philipp Sh 14 August 2018 в 17:12

Другие вопросы по тегам:

Похожие вопросы: