在學tornado的時候涉及如下數據庫操做,如今暫時使用mysql數據庫,因此選擇了一個比較好用的ORM工具sqlalchemy,順便記一下使用過程html
首先安裝mysqlpython
pip安裝必要的庫:pip install sqlalchemymysql
下載mysql-python驅動:
http://www.codegood.com/archives/129
若是是32位版本的windows選win32,若是是64的能夠選擇amd64web
首先須要一個數據庫配置文件sql
# -*- coding: utf-8 -*- DB_HOST = '127.0.0.1' # DB_HOST = '127.0.0.1' DB_USER = 'root' # DB_USER = 'root' DB_PWD = '' # DB_PWD = '084358' DB_NAME = 'my404'
from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() #create Base lei engine = create_engine('mysql://%s:%s@%s/%s?charset=utf8' % (DB_USER, DB_PWD, DB_HOST, DB_NAME), encoding='utf-8', echo=False, pool_size=100, pool_recycle=10)
這裏我寫了一個db.py文件,目錄在tornado項目根目錄下的mod.databases下數據庫
接下來是一段相似於orm裏實體類部分的代碼,我一樣放在了mod.databases下,名字爲tables.pywindows
from sqlalchemy import Column, String, Integer, VARCHAR,ForeignKey, Float from sqlalchemy.orm import relationship,backref from db import engine,Base class Article(Base): __tablename__ = 'articles' user = Column(VARCHAR(20),primary_key = True) title = Column(VARCHAR(40)) time = Column(VARCHAR(20)) content = Column(VARCHAR(2000))
每一個類對應一個表,上方導入必要的庫和db裏的一些配置信息,注意必定要設置一項爲primary_key,否則在查詢時會報錯Could not assemble any primary key columns for mapped table緩存
這就是大概須要配置的部分,若是須要用新的表就在tables.py裏面加入新的類就行了session
以下,在本身的main.py裏須要對定義的application裏面作一下數據庫的設置,經過self.db修改屬性來設置一些和數據庫相關的操做。可是具體其中的屬性還不太瞭解,就先放着了。app
class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", IndexHandler), ] settings = dict( debug=True, static_path=os.path.join(os.path.dirname(__file__),"static"), template_path=os.path.join(os.path.dirname(__file__), "templates") ) tornado.web.Application.__init__(self, handlers, **settings) self.db = scoped_session(sessionmaker(bind=engine, autocommit=False, autoflush=True, expire_on_commit=False)) if __name__ == '__main__': tornado.options.parse_command_line() Application().listen(options.port, address='127.0.0.1') tornado.ioloop.IOLoop.instance().start()
在具體的handler裏使用時以下
from tornado.httpclient import HTTPRequest, AsyncHTTPClient from mod.databases.tables import Article import tornado.web import tornado.gen import urllib class DbHandler(tornado.web.RequestHandler): @property def db(self): return self.application.db def get(self): data = self.db.query(Article).all() for item in data: print item.content
一方面對使用的實體類要進行導入,如
from mod.databases.tables import Article
另外一方面db函數上方
@property
標註是python關於屬性的標註,有了這個標註就可使用self.db來直接獲取鏈接對象,而不須要加上括號self.db(),看起來會比較直觀
具體的查詢語句就是
data = self.db.query(Article).all()
這裏我從數據庫裏取出數據後只把每一項的content列輸出了,並無進行其餘操做。
其餘的使用方法能夠參考sqlalchemy的官方文檔
http://docs.sqlalchemy.org/en/rel_1_0/or...
new_user = User(user_email = email,user_name = name,user_psd = psd) self.db.add(new_user) self.db.commit() self.db.close()#用完後關閉數據庫鏈接,不然可能 致使這次鏈接時間過長而未操做,數據庫鏈接超時的問題
須要注意的地方是commit函數,若是沒有commit,那麼self.db裏仍是保存着以前的信息,這樣說彷佛不太明白,可是我在使用的過程當中發生了一個這樣的情景:
我搭建了一個小網站,能夠用於註冊登陸,在我註冊時我先檢測相關信息是否合法,例如用戶名(郵箱)是否已存在:
user = self.db.query(User).filter(User.user_email == self.email).first() if user!=None: 表示用戶名已存在 返回錯誤信息 else: 用戶名不存在,能夠註冊 new_user = User(user_email = email,user_name = name,user_psd = psd) self.db.add(new_user) self.db.commit()
但緊接着,我又作了一件沒有什麼必要作的事情(請不要吐槽,我只是這麼寫了一下,其實目的是檢測一下這個用戶是否在數據庫中存在了,而後返回註冊成功的信息
user = self.db.query(User).filter(User.user_name == name).first() if(user.user_email == email): self.db.commit() data["status"] = 200 data["data"] = "Register Success" 標記2 self.write(data)
可是這麼作令我出現了一個麻煩
在我註冊成功後,我從數據庫中緊接着刪除了這個用戶,而後從新註冊,這時候他顯示這個用戶仍是存在的…
在我將tornado的服務重啓後,用一樣的用戶名去註冊,發現這時候又不顯示該用戶存在了,因而註冊成功
以後我在標記2處加了一句self.db.commit()後這個問題就再也不出現了。
通常咱們還會採起的操做是
緣由是由於self.db實際上是sqlalchemy的scoped_session,他至關於未commit時有個緩存,查詢結果也會緩存在其中。因而雖然數據庫裏刪除了某用戶,可是在刪除以前我作了一次對這個用戶的查詢,致使self.db裏緩存了這個用戶。因此下次他直接在緩存裏找到了這個用戶。
重啓服務後緩存清掉了,也就恢復正常和數據庫保持同步了…
具體的緣由還得看看文檔…若是有知道的同窗歡迎指導啊=.=