2014-09-16 2 views
0

Проблема с созданием MVC-дизайна с помощью Cherrypy/MySQL. Вот настройки: (предполагается, что все импорт правильны)cherrypy mvc with mysql issue

##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' 

не знаю, почему, не могли бы вы мне точку в правильном направлении? Я могу получить соединение и вывести информацию с контроллера.py в индекс User, но не в model.py? Пожалуйста, помогите .. спасибо.

ответ

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 
+0

это работает для меня, спасибо за помощь. – triston