gpt4 book ai didi

python - CherryPy session 和大对象?

转载 作者:行者123 更新时间:2023-11-28 22:45:21 25 4
gpt4 key购买 nike

我有一个最初使用基于文件的 session 编写的 CherryPy Web 应用程序。我有时会在 session 中存储潜在的大对象,例如运行报告的结果——我提供了以各种格式下载报告结果的选项,并且我不想在由于可能获得不同的数据,用户选择下载。在使用基于文件的 session 时,这工作正常。

现在我正在研究使第二台服务器联机的可能性,因此我需要能够在服务器之间共享 session 数据,为此使用 memchached session 存储类型似乎是最合适的。我简要地查看了使用 PostgreSQL 存储类型,但是这个选项的文档非常少,而且据我所知,它很可能被破坏了。所以我实现了 memcached 选项。

但是,现在我遇到了一个问题,当我尝试将某些对象保存到 session 中时,我收到“AssertionError:未设置 id xxx 的 session 数据”。我假设这是由于对象大小超过了 CherryPy session 后端或 memcached 中设置的任意限制,但我真的不知道,因为异常没有告诉我为什么没有设置它。我已将 memcached 中的对象大小限制增加到最大 128MB 以查看是否有帮助,但它没有 - 而且这可能不是一个安全的选择。

那么我的解决方案是什么?有什么方法可以使用 memcached session 存储来存储任意大的对象吗?我是否需要为这些对象“推出我自己的”基于数据库或类似的解决方案?问题可能不是基于大小的吗?还是我缺少其他选项?

最佳答案

我使用 mysql 来处理我的 cherrypy session 。只要该对象是可序列化的(可以被腌制),您就可以将其作为 blob(二进制大对象)存储在 mysql 中。这是您希望用于 mysql session 存储的代码...

https://bitbucket-assetroot.s3.amazonaws.com/Lawouach/cherrypy/20111008/936/mysqlsession.py?Signature=gDmkOlAduvIZS4WHM2OVgh1WVuU%3D&Expires=1424822438&AWSAccessKeyId=0EMWEFSGA12Z1HF1TZ82

"""
MySQLdb session module for CherryPy by Ken Kinder <http://kenkinder.com/>

Version 0.3, Released June 24, 2000.

Copyright (c) 2008-2009, Ken Kinder
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

* Neither the name of the Ken Kinder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
import MySQLdb
import cPickle as pickle
import cherrypy
import logging
import threading

__version__ = '0.2'

logger = logging.getLogger('Session')

class MySQLSession(cherrypy.lib.sessions.Session):
##
## These can be over-ridden by config file
table_name = 'web_session'
connect_arguments = {}

SCHEMA = """create table if not exists %s (
id varchar(40),
data text,
expiration_time timestamp
) ENGINE=InnoDB;"""

_database = None

def __init__(self, id=None, **kwargs):
logger.debug('Initializing MySQLSession with %r' % kwargs)
for k, v in kwargs.items():
setattr(MySQLSession, k, v)

self.db = self.get_db()
self.cursor = self.db.cursor()

super(MySQLSession, self).__init__(id, **kwargs)

@classmethod
def get_db(cls):
##
## Use thread-local connections
local = threading.local()
if hasattr(local, 'db'):
return local.db
else:
logger.debug("Connecting to %r" % cls.connect_arguments)
db = MySQLdb.connect(**cls.connect_arguments)
cursor = db.cursor()
cursor.execute(cls.SCHEMA % cls.table_name)
db.commit()
local.db = db

return db

def _load(self):
logger.debug('_load %r' % self)
# Select session data from table
self.cursor.execute('select data, expiration_time from %s '
'where id = %%s' % MySQLSession.table_name, (self.id,))
row = self.cursor.fetchone()
if row:
(pickled_data, expiration_time) = row
data = pickle.loads(pickled_data)

return data, expiration_time
else:
return None

def _save(self, expiration_time):
logger.debug('_save %r' % self)
pickled_data = pickle.dumps(self._data)

self.cursor.execute('select count(*) from %s where id = %%s and expiration_time > now()' % MySQLSession.table_name, (self.id,))
(count,) = self.cursor.fetchone()
if count:
self.cursor.execute('update %s set data = %%s, '
'expiration_time = %%s where id = %%s' % MySQLSession.table_name,
(pickled_data, expiration_time, self.id))
else:
self.cursor.execute('insert into %s (data, expiration_time, id) values (%%s, %%s, %%s)' % MySQLSession.table_name,
(pickled_data, expiration_time, self.id))
self.db.commit()

def acquire_lock(self):
logger.debug('acquire_lock %r' % self)
self.locked = True
self.cursor.execute('select id from %s where id = %%s for update' % MySQLSession.table_name,
(self.id,))
self.db.commit()

def release_lock(self):
logger.debug('release_lock %r' % self)
self.locked = False
self.db.commit()

def clean_up(self):
logger.debug('clean_up %r' % self)
self.cursor.execute('delete from %s where expiration_time < now()' % MySQLSession.table_name)
self.db.commit()

def _delete(self):
logger.debug('_delete %r' % self)
self.cursor.execute('delete from %s where id=%%s' % MySQLSession.table_name, (self.id,))
self.db.commit()

def _exists(self):
# Select session data from table
self.cursor.execute('select count(*) from %s '
'where id = %%s and expiration_time > now()' % MySQLSession.table_name, (self.id,))
(count,) = self.cursor.fetchone()
logger.debug('_exists %r (%r)' % (self, bool(count)))
return bool(count)

def __del__(self):
logger.debug('__del__ %r' % self)
self.db.commit()
self.db.close()
self.db = None

def __repr__(self):
return '<MySQLSession %r>' % (self.id,)

cherrypy.lib.sessions.MysqlSession = MySQLSession

然后你的 webapp.py 看起来像这样......

 from mysqlsession import MySQLSession 
import cherrypy
import logging

logging.basicConfig(level=logging.DEBUG)

sessionInfo = {
'tools.sessions.on': True,
'tools.sessions.storage_type': "Mysql",
'tools.sessions.connect_arguments': {'db': 'sessions'},
'tools.sessions.table_name': 'session'
}

cherrypy.config.update(sessionInfo)

class HelloWorld:
def index(self):
v = cherrypy.session.get('v', 1)
cherrypy.session['v'] = v+1
return "Hello world! %s" % v

index.exposed = True

cherrypy.quickstart(HelloWorld())

如果你需要把一些东西放在那里做这样的事情......

import pickle

pickledThing = pickle.dumps(YourObject.GetItems(), protocol=0, fix_imports=False)

希望这对您有所帮助!

关于python - CherryPy session 和大对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28705661/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com