【问题标题】:cherrypy mvc with mysql issue带有mysql问题的cherrypy mvc
【发布时间】:2014-09-16 06:03:44
【问题描述】:

使用 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 中? 请帮忙..谢谢。

【问题讨论】:

    标签: python mysql cherrypy


    【解决方案1】:

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

    就我个人而言,我对 CherryPy 应用程序使用了相同的职责分离概念,一种 MVC,因此有两种可能的方式来实现您想要的。

    设计说明

    我想指出,线程映射数据库连接的简单解决方案(至少在 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 等。

    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
    

    【讨论】:

      猜你喜欢
      • 2013-11-05
      • 2011-04-13
      • 2023-03-27
      • 2014-11-23
      • 2014-02-23
      • 2020-04-14
      • 1970-01-01
      • 2010-12-30
      • 2017-10-04
      相关资源
      最近更新 更多