Tornado中sqlalchemy使用

在學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裏緩存了這個用戶。因此下次他直接在緩存裏找到了這個用戶。
重啓服務後緩存清掉了,也就恢復正常和數據庫保持同步了…

具體的緣由還得看看文檔…若是有知道的同窗歡迎指導啊=.=

相關文章
相關標籤/搜索