在学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里缓存了这个用户。因此下次他直接在缓存里找到了这个用户。
重启服务后缓存清掉了,也就恢复正常和数据库保持同步了…
具体的缘由还得看看文档…若是有知道的同窗欢迎指导啊=.=