App Engine: ReferencePropertyResolveError в Google App Engine? - PullRequest
0 голосов
/ 29 ноября 2011

Пожалуйста, помогите мне понять, почему эта ошибка в App Engine (Python 2.5, высокая репликация)?

Traceback (most recent call last):
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/_webapp25.py", line 703, in __call__ 
    handler.post(*groups)
File "/base/data/home/apps/s~apptest/1.354937136776013205/main.py", line 963, in post
    get_purchases_for_user(pur.user, pur.car.model)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 3592, in __get__
    reference_id.to_path())
ReferencePropertyResolveError: ReferenceProperty failed to be resolved: [u'User', 374836L]

Контекст : приложение о рекомендациях купить автомобили.

Когда это происходит : примерно 2 раза на каждые 100 транзакций приблизительно, поэтому на самом деле я не знаю, когда и почему.

Где объект pur в коде определяется как:

allPurchases = models.Purchase.all()
for pur in allPurchases:
   car = get_purchases_for_user(pur.user, pur.car.model)

Также я поместил этот код раньше, и я получил ту же ошибку, конечно, ссылаясь на эту строку

logging.error("Object user: %s, Car Model %s" % {str(pur.user), pur.car.model})

Итак, проблема не вв функции get_purchases_for_user

А вот модели в хранилище данных:

class User(db.Model):
    username = db.StringProperty(
        required=True)
    name = db.StringProperty(
        required=True)
    email = db.EmailProperty(
        required=True)
    password = db.StringProperty(
        required=True)

class Car(db.Model):
    model = db.StringProperty()
    name = db.StringProperty()
    year = db.DateTimeProperty()

class Purchase(db.Model):
    user = db.ReferenceProperty(User,
        collection_name='recommendations')
    car = db.ReferenceProperty(Car,
        collection_name='recommendations')
    when = db.DateTimeProperty(
        auto_now=True)

Ответы [ 2 ]

3 голосов
/ 09 декабря 2011

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

2 голосов
/ 01 декабря 2011

Я склоняюсь к проблеме, связанной с высокой репликацией хранилища данных и отсутствием гарантированной согласованности.Из документации Google:

Однако в хранилище данных с высокой репликацией запросы по группам сущностей (иными словами, запросы без предков) могут возвращать устаревшие результаты.Чтобы получить строго согласованные результаты запроса в среде высокой репликации, необходимо выполнить запрос по одной группе объектов.Этот тип запроса называется запросом-предком.

Запросы-предки работают, потому что группы сущностей являются единицей согласованности: все операции применяются ко всей группе.Запросы предков не будут возвращать данные, пока не будет обновлена ​​вся группа объектов.Таким образом, данные, возвращаемые из запросов предков по группам сущностей, строго согласованы.

Если ваше приложение использует строго согласованные результаты для определенных запросов, вам, возможно, придется изменить способ хранения сущностей в приложении.На этой странице обсуждаются рекомендации по работе с данными, хранящимися в хранилище данных с высокой репликацией.Давайте посмотрим, как это работает, используя примеры приложений гостевой книги для Master / Slave и High Replication Datastores, соответственно.

Таким образом, вы могли бы запросить что-то, что только что было написано, но не распространилось по всейвся база данных.В результате, когда вы ссылаетесь на свойство, оно как если бы оно никогда не существовало или не было удалено.

Похоже, вы используете .all () для извлечения данных.Я бы предложил переписать его, чтобы использовать GQL и запросы предков, если это возможно.Или, возможно, ограничение данных во времени для распространения.Документы по запросам предков: http://code.google.com/appengine/docs/python/datastore/queries.html#Ancestor_Queries

...