Django: AttributeError: обектът 'bool' няма атрибут 'expire'

В момента използвам модула redis.py на Andy McCurdy, за да взаимодействам с Redis от Django

Прехвърлям определени задачи на заден план с помощта на Celery.

Ето една от задачите ми:

import redis
pool = redis.ConnectionPool(host='XX.XXX.XXX.X', port=6379, db=0, password='password')
r_server = redis.Redis(connection_pool=pool)
pipe = r_server.pipeline()

# The number of seconds for two months
seconds = 5356800

@shared_task
def Activity(userID, object_id, timestamp):
        timestamp = int(timestamp)
        # Create Individual activity for each.
        activity_key = 'invite:activity:%s:%s' % (userID, timestamp)
        mapping = dict(
            user_id = userID,
            object_id = object_id)
        pipe.hmset(activity_key, mapping).expire(activity_key, seconds).execute()

Всеки път, когато се извика тази задача, получавам следната грешка:

AttributeError: 'bool' object has no attribute 'expire'

На какво може да се дължи това?

По-късно направих тест в конзола на Python, за да видя дали има нещо нередно със синтаксиса ми, но всичко работи точно както планирах. И така, какво може да е причината за тази грешка?

АКТУАЛИЗАЦИЯ

Мисля, че изтичането оценява резултата от hmset(activity_key, картографиране). Това е странно! expire е метод за канал.

ВТОРА АКТУАЛИЗАЦИЯ

Намерих работа за момента. Изглежда, че това се случва само в Celery. Родните изгледи на Django и конзолата на python не проявяват това поведение. Изглежда, че оценява резултата от израза преди него. Ако някой от вас се сблъска с този проблем, ето решение.

pipe.hmset(activity_key, mapping)
pipe.lpush('mylist', 1)
pipe.expire('mylist', 300)
pipe.execute()

Това трябва да работи и да не ви създава проблеми. Честито кодиране!


person deadlock    schedule 23.03.2014    source източник


Отговори (1)


pipe.hmset() не връща тръбопровода; не можете да лансирате обажданията тук. Вместо това се връща булево значение (вероятно показващо дали извикването hmset() е успешно).

Извикайте отделно методите .expire() и .execute():

pipe.hmset(activity_key, mapping)
pipe.expire(activity_key, seconds)
pipe.execute()

Подозирам, че трябва да създадете тръбопровод в рамките на задачата Celery, вместо да използвате повторно глобален тук. Преместете pipe = r_server.pipeline() в рамките на дейността.

person Martijn Pieters    schedule 23.03.2014
comment
Докато актуализирах въпроса си, за да покажа констатациите си какво работи, вие бяхте отговорили в точното време! Ще маркирам отговора ви като правилен. - person deadlock; 23.03.2014
comment
Освен това това поведение се случва само в Celery. Пробвах го в конзолата и се получи. - person deadlock; 23.03.2014
comment
Да; обикновено методите Pipeline трябва да са верижни, което ме кара да се чудя малко какво се случва тук. - person Martijn Pieters; 23.03.2014
comment
да, точно това правя. Имам pipe = r_server.pipeline() като глобална променлива, но защо това създава проблеми? - person deadlock; 23.03.2014
comment
Обект pipeline има състояние, наистина не трябва да споделяте това състояние между нишки, например. - person Martijn Pieters; 23.03.2014
comment
Мартийн, сега разбирам! Благодаря ти! Предполагам, че мога също да използвам pipe.reset() след изявлението execute() правилно? - person deadlock; 28.03.2014
comment
Не и ако имате множество нишки, използващи този един глобален тръбен обект. pipe.reset() е добре, ако можете да гарантирате последователен достъп. - person Martijn Pieters; 28.03.2014