【问题标题】:caching mysql query returned by Python script缓存 Python 脚本返回的 mysql 查询
【发布时间】:2013-03-22 21:32:55
【问题描述】:

我有这个 python '2.6.4' 脚本:

#!/usr/bin/python
import MySQLdb
import csv
import pprint

db = MySQLdb.connect(host="localhost", # The Host
                     user="username", # username
                      passwd="password", # password
                      db="dbname") # name of the data base

cursor = db.cursor() 

cursor.execute("SELECT name, id, city, storeid FROM Products;")

StudentsData = cursor.fetchall()
pprint.pprint(StudentsData)

这个查询返回数百万行,执行需要3 minutes,每天运行20次,每个用户必须等待三分钟才能获取输出。

我在想caching 它,但我不知道如何在 python 中做到这一点, 这是一个好主意,如果是这样,我该怎么做,使用上面的代码。

如果有更好的方法,请帮助我?

【问题讨论】:

  • 是否缓存完全由您决定。过时的数据会成为问题吗?

标签: python mysql performance caching


【解决方案1】:

是否缓存完全由您决定。过时的数据会成为问题吗?

我能想到的最简单的缓存方案是使用 Python 的pickle module 如下所示:

import MySQLdb
import csv
import pprint
import time

MAX_CACHE_AGE = 60*20  # 20 Minutes
CACHE_FILENAME = 'results.cache'

with open(CACHE_FILENAME, 'r') as cache:
    cached = pickle.load(cache)

if(time.time() > cached['timestamp'] + MAX_CACHE_AGE):
    # Cache too old, run query
    db = MySQLdb.connect(host="localhost", # The Host
                     user="username", # username
                     passwd="password", # password
                     db="dbname") # name of the data base

    cursor = db.cursor() 
    cursor.execute("SELECT name, id, city, storeid FROM Products;")
    StudentsData = cursor.fetchall()

    # Update cache file
    data = {'results': StudentsData, 'timestamp':time.time()}
    with open(CACHE_FILENAME, 'w') as cache:
        pickle.dump(data, cache)

else:
    # Cached data is fresh enough, use that
    StudentsData = cached['results']

pprint.pprint(StudentsData)

您需要手动初始化一次results.cache 文件。


编辑

with 语法是一种上下文管理器,在 Python 2.5 中引入。

with open(CACHE_FILENAME, 'r') as cache:
    cached = pickle.load(cache)

可以改写为

cached = open(CACHE_FILENAME, 'r')
cached = pickle.load(cache)
cached.close()

EDIT2

经过长时间的聊天讨论,以下工作:

import MySQLdb
import csv
import pprint
import time
import pickle

MAX_CACHE_AGE = 60*20  # 20 Minutes
CACHE_FILENAME = 'results.cache'

regen = False
try:
    with open(CACHE_FILENAME, 'r') as cache:
        cached = pickle.load(cache)

    if(time.time() > cached['timestamp'] + MAX_CACHE_AGE):
        print("Cache too old: regenerating cache")
        regen = True
    else:
        print("Cached data is fresh enough: loading results from cache")

except IOError:
    print("Error opening %s: regenerating cache" % CACHE_FILENAME)
    regen = True

if(regen):
    # Cache too old, run query
    db = MySQLdb.connect(host="localhost", # The Host
                     user="username", # username
                     passwd="password", # password
                     db="dbname") # name of the data base

    cursor = db.cursor()
    cursor.execute("SELECT name, id, city, storeid FROM Products;")
    StudentsData = cursor.fetchall()
    cursor.close()

    # Update cache file
    data = {'results': StudentsData, 'timestamp':time.time()}
    with open(CACHE_FILENAME, 'w') as cache:
        pickle.dump(data, cache)

else:
    # Cached data is fresh enough, use that
    StudentsData = cached['results']


print StudentsData

【讨论】:

  • 非常感谢你的好例子!!我相信这正是我正在寻找的,唯一的事情是我得到了这个错误,with open(CACHE_FILENAME, 'r') as cache: ^ SyntaxError: invalid syntax 我应该安装一些东西让脚本工作吗?谢谢!
  • 你错过了as吗?
  • 我得到了有和没有 as 的错误。我试图删除它,看看是否能解决问题。但它没有。
  • 您使用的是什么版本的 Python?支持上下文管理器之前的版本?如果您使用的是 Python ,我以另一种模式进行了编辑
  • 对不起,我没有发布。 '2.6.4'
【解决方案2】:

在 Python 3 中,对于一个非常简单的情况,您可以查看 functools.lru_cache:http://docs.python.org/3.2/library/functools.html#functools.lru_cache

对于更复杂的缓存,烧杯可能是要走的路:http://beaker.readthedocs.org/en/latest/caching.html

【讨论】:

  • python2的任何替代品??
猜你喜欢
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2014-06-25
  • 2023-02-09
相关资源
最近更新 更多