Django: AttributeError: 'bool'对象没有'expire'属性

0 投票
1 回答
1039 浏览
提问于 2025-04-17 23:28

我现在正在使用Andy McCurdy的redis.py模块,通过Django与Redis进行交互。

我把一些任务放到后台去处理,使用的是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控制台里测试了一下,看看我的语法有没有问题,但一切都正常,跟我预想的一样。那么这个错误可能是什么原因呢?

更新

我觉得expire这个方法是在评估hmset(activity_key, mapping)的结果。这听起来很奇怪!expire是一个管道的方法。

第二次更新

我暂时找到了一种解决办法。似乎这个问题只在Celery中出现。原生的Django视图和Python控制台没有这个问题。它似乎是在评估前面表达式的结果。如果你们遇到这个问题,这里有一个解决办法。

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

这个方法应该可以正常工作,不会给你带来任何问题。祝你编码愉快!

1 个回答

2

pipe.hmset() 这个方法 不会 返回管道,所以你不能把多个调用连在一起。它返回的是一个布尔值(可能表示 hmset() 调用是否成功)。

你需要分别调用 .expire().execute() 方法:

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

我怀疑你需要在 Celery 任务中创建一个新的管道,而不是在这里重复使用一个全局的。把 pipe = r_server.pipeline() 移到活动内部。

撰写回答