在Django中如何缓存从BigQuery拉取的数据?
Django缓存BigQuery查询结果的实现方案
Django 自带成熟的缓存框架,可直接用来避免重复拉取 BigQuery 数据,以下是两种常用实现方案:
方案1:全视图缓存(适合所有用户返回内容一致的场景)
直接使用 Django 提供的视图缓存装饰器,对整个视图的返回结果做缓存,操作最简单。
- 先在
settings.py中配置缓存后端,本地开发可使用内存缓存:
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'bq_cache_space', } } # 生产环境推荐替换为 Redis 缓存,配合 django-redis 库使用即可
- 给视图加缓存装饰器,示例中缓存时长为15分钟,可根据数据更新频率调整:
from django.views.decorators.cache import cache_page @cache_page(60 * 15) def index(request): # 保留原有业务逻辑不变 client = bigquery.Client() # ... 其余原有代码
方案2:自定义缓存颗粒度(适合视图存在其他动态内容的场景)
如果视图除了 BigQuery 数据外还有其他需要动态渲染的内容,可以只缓存处理后的 JSON 数据,使用 Django 低级缓存 API 自主控制缓存逻辑:
修改后的视图代码如下:
from django.core.cache import cache def index(request): # 优先从缓存读取处理好的JSON数据 data_json = cache.get('bq_processed_data') # 缓存未命中时执行拉取和处理逻辑 if not data_json: client = bigquery.Client() dataset_id = "project-id.dataset-id" tables = client.list_tables(dataset_id) tables_list = [table.table_id for table in tables] data_list = [] for table_id in tables_list: query_string = f""" SELECT * FROM `project-id.dataset-id.{table_id}` """ query_job = ( client.query(query_string) .result() ) records = [dict(row) for row in query_job] data_list.extend(records) df = pd.DataFrame(data_list) # ... 原有pandas数据处理逻辑 data_json = df.to_json(orient="records") # 将结果写入缓存,设置15分钟过期 cache.set('bq_processed_data', data_json, 60 * 15) context = {'data_json': data_json} return render(request, 'template_name', context)
注意事项
- 缓存过期时间可根据BigQuery数据的更新频率调整,若数据每日更新一次可设置为86400秒(24小时)
- 若需要数据更新后立即生效,可编写Django管理命令主动清除缓存:
cache.delete('bq_processed_data') - 分布式部署场景必须使用Redis、Memcached等共享缓存后端,避免本地内存缓存多进程数据不一致问题
- 若不同用户访问的数据存在差异,缓存键需要拼接用户唯一标识,例如
cache.get(f'bq_data_{request.user.id}')
内容的提问来源于stack exchange,提问作者Owenn
相关产品推荐
相关产品推荐

