与mysql问题的cherrypy mvc

时间:2014-09-16 06:03:44

标签: python mysql cherrypy

使用Cherrypy / MySQL设置MVC设计时遇到问题。这是设置:(假设所有导入都是正确的)

##controller.py
class User(object):

    def __init__(self):
       self.model = model.User()

    @cherrypy.expose
    def index(self):
       return 'some HTML to display user home'


## model.py
class Model(object):
    _db = None

    def __init__(self):
        self._db = cherrypy.thread_data.db


class User(Model):
    def getuser(self, email):
        #get the user with _db and return result


##service.py
class UserService(object):
     def __init__(self):
        self._model = model.User()

     def GET(self, email):
        return self._model.getuser(email)


##starting the server

user = controller.User()
user.service = service.UserService()
cherrypy.tree.mount(user, '/user', self.config)
#app.merge(self.config)

cherrypy.engine.subscribe("start_thread", self._onThreadStart)

self._onThreadStart(-1)

def _onThreadStart(self, threadIndex):
    cherrypy.thread_data.db = mysql.connect(**self.config["database"])

if __name__ == '__main__':
    cherrypy.engine.start()
    cherrypy.engine.block()

上面的代码在model.py中的行中有错误:cherrypy.thread_data.db。 我得到了:

AttributeError: '_ThreadData' object has no attribute 'db' 

不确定原因,请你指点我正确的方向?我可以获取连接,并从用户索引的controller.py中提取信息,但不在model.py中提取信息? 请帮忙..谢谢。

1 个答案:

答案 0 :(得分:1)

CherryPy不会为您决定使用哪些工具。您可以选择最适合您和您的任务的工具。因此,CherryPy不会设置任何数据库连接,cherrypy.thread_data.db,这是你的工作。

我个人使用相同的责任分离概念,一种MVC,用于我的CherryPy应用程序,所以有两种可能的方法来实现你想要的。

设计说明

我想指出,线程映射数据库连接的简单解决方案,至少在MySQL的情况下,在实践中运行良好。而且可能没有必要使用更复杂的老式连接池。

然而,有些观点不应该被忽视。您的数据库连接可能会被杀死,丢失或处于不允许您对其进行查询的任何其他状态。在这种情况下,必须重新连接。

还要注意避免线程之间的连接共享,因为它会导致难以调试的错误和Python崩溃。在您的示例代码中,它可能与服务调度程序及其缓存有关。

引导阶段

在设置配置的代码中,安装CherryPy应用程序等

bootstrap.py

# ...

import MySQLdb as mysql

def _onThreadStart(threadIndex):
  cherrypy.thread_data.db = mysql.connect(**config['database'])

cherrypy.engine.subscribe('start_thread', _onThreadStart)

# useful for tests to have db connection on current thread 
_onThreadStart(-1)

model.py

import cherrypy
import MySQLdb as mysql


class Model(object):
  '''Your abstract model'''

  _db = None


  def __init__(self):
    self._db = cherrypy.thread_data.db

    try:
      # reconnect if needed
      self._db.ping(True)
    except mysql.OperationalError:
      pass

几年前我写了一篇完整的CherryPy部署教程cherrypy-webapp-skeleton。您可以查看代码,因为演示应用程序正是使用这种方法。

模型属性

为了减少代码耦合并避免导入周期,将所有与数据库相关的代码移动到模型模块可能是个好主意。它可能包括初始连接查询,例如设置操作时区,使MySQLdb转换器具有timzeone-aware等。

model.py

class Model(object):

  def __init__(self):
    try:
      # reconnect if needed
      self._db.ping(True)
    except mysql.OperationalError:
      pass

  @property
  def _db(self):
    '''Thread-mapped connection accessor'''

    if not hasattr(cherrypy.thread_data, 'db'):
      cherrypy.thread_data.db = mysql.connect(**config['database'])

    return cherrypy.thread_data.db