Pylons 入门实例教程 – 数据库操作
来源:互联网 发布:天猫魔盒如何安装网络 编辑:程序博客网 时间:2024/05/18 03:45
前面两篇入门,讲述了 Pylons 大致开发的流程、表单以及文件上传,思路大致跟传统的开发类似。本篇简单讲述下在 Pylons 如何使用数据库。
本篇侧重点是使用 ORM 框架 SQLAlchemy。现在 Python 社区里关注度比较高的大概有三:SQLAlchemy、SQLObject 和 Storm。其实本人最早是研究了一下 Storm,后来听虾哥(@marchliu)在应用里不是很爽之,遂关注了下他推荐的 SQLAlchemy。当然,你也可以对应数据库的 DB-API 库来进行操作。
示例代码的数据库是 PostgreSQL,对应的 Python 库使用的是 psycopg2。至于 Pg 配置和使用这里不再累赘,请狗之。
Debian/Ubuntu 安装很简单:
sudo aptitude install python-psycopg2
建立一个测试数据库,比如 test:
smallfish@debian:~/workspace/python/hello$ su postgrespostgres@debian:/home/smallfish/workspace/python/hello$ createdb -O smallfish testpostgres@debian:/home/smallfish/workspace/python/hello$ exitsmallfish@debian:~/workspace/python/hello$ psql -h 127.0.0.1 -p 5432 -U smallfish test用户 smallfish 的口令:psql (8.4.4)SSL连接 (加密:DHE-RSA-AES256-SHA,位元:256)输入 "help" 来获取帮助信息.test=#
数据库的部分已经OK,下面就是来倒腾 Pylons 啦。
建立新项目,加入支持数据库部分,注意 Enter sqlalchemy那个选项,默认是 False,改成 True:
smallfish@debian:~/workspace/python$ paster create -t pylons hellodbSelected and implied templates: Pylons#pylons Pylons application templateVariables: egg: hellodb package: hellodb project: hellodbEnter template_engine (mako/genshi/jinja2/etc: Template language) ['mako']:Enter sqlalchemy (True/False: Include SQLAlchemy 0.5 configuration) [False]: TrueCreating template pylonsCreating directory ./hellodb
改成 True 之后在自动生成的 development.ini 里就有对应的数据库配置选项了。
再建立新的 db controller:
smallfish@debian:~/workspace/python$ cd hellodb/smallfish@debian:~/workspace/python/hellodb$ paster controller dbCreating /home/smallfish/workspace/python/hellodb/hellodb/controllers/db.pyCreating /home/smallfish/workspace/python/hellodb/hellodb/tests/functional/test_db.py
编辑 development.ini,添加数据库配置部分。smallfish:123456 是对应的 PostgreSQL 用户名/密码,127.0.0.1:5432 是对应的主机地址/端口号,最后的test则是数据库名。
# SQLAlchemy database URLsqlalchemy.url = postgresql://smallfish:123456@127.0.0.1:5432/test
编辑 hellodb/model/__init__.py,加上一个叫 msg 的表和字段的定义:
"""The application's model objects"""from hellodb.model.meta import Session, metadatafrom sqlalchemy import orm, schema, typesfrom datetime import datetimedef init_model(engine): """Call me before using any of the tables or classes in the model""" Session.configure(bind=engine)def now(): return datetime.now()msg_table = schema.Table('msg', metadata, schema.Column('id', types.Integer, schema.Sequence('msg_seq_id', optional=True), primary_key=True), schema.Column('content', types.Text(), nullable=False), schema.Column('addtime', types.DateTime(), default=now),)class Msg(object): passorm.mapper(Msg, msg_table)
示例 Msg 表很简单,三个字段:ID、内容和时间。
上面的代码除去导入 sqlclchemy 包里几个库,基本上有一个对应表的字段定义,还有一个空的 Msg 对象。
最后一行,则是做一个 map 的动作,把 Msg 映射到 msg_table 上。
下面是不是要在数据库里建立对应的表呢?有个简单的办法 可以初始化数据库:paster setup-app development.ini:
smallfish@debian:~/workspace/python/hellodb$ paster setup-app development.iniRunning setup_config() from hellodb.websetup20:08:43,619 INFO [sqlalchemy.engine.base.Engine.0x...854c] [MainThread] select version()20:08:43,619 INFO [sqlalchemy.engine.base.Engine.0x...854c] [MainThread] {}20:08:43,625 INFO [sqlalchemy.engine.base.Engine.0x...854c] [MainThread] select current_schema()20:08:43,625 INFO [sqlalchemy.engine.base.Engine.0x...854c] [MainThread] {}20:08:43,631 INFO [sqlalchemy.engine.base.Engine.0x...854c] [MainThread] select relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where n.nspname=current_schema() and lower(relname)=%(name)s20:08:43,631 INFO [sqlalchemy.engine.base.Engine.0x...854c] [MainThread] {'name': u'msg'}20:08:43,637 INFO [sqlalchemy.engine.base.Engine.0x...854c] [MainThread]CREATE TABLE msg ( id SERIAL NOT NULL, content TEXT NOT NULL, addtime TIMESTAMP WITHOUT TIME ZONE, PRIMARY KEY (id))20:08:43,637 INFO [sqlalchemy.engine.base.Engine.0x...854c] [MainThread] {}20:08:43,732 INFO [sqlalchemy.engine.base.Engine.0x...854c] [MainThread] COMMIT
可以看到上面的输出日志,包括了建表的SQL语句。其中 SERIAL 对应上面 __init__.py 里 Column 的 Seq 定义。serial 类型 在 PostgreSQL 可以看成类似 MySQL 的自增ID(auto_increment) 。
现在进入 PostgreSQL 查询数据库,就可以看到表以及序列已经建立。
test=# /d 关联列表 架构模式 | 名称 | 型别 | 拥有者----------+------------+--------+----------- public | msg | 资料表 | smallfish public | msg_id_seq | 序列数 | smallfish(2 行记录)
到这里,准备工作已经完毕,包括了初始化数据库,配置文件还有示例 controller。
下面就在 controller 代码里增加读写数据库的功能吧。
首先建立一个表单模板 db.htm ,用来添加并保存到数据库表中:
<form action="/db/add" method="post"> <input type="text" name="content" /> <br /> <input type="submit" value="save" /></form>
对应 controller index 修改成,很简单。返回到模板:
class DbController(BaseController): def index(self): return render('/db.htm')
添加 add 方法,对应上面 form 中的 /db/add 路径:
def add(self): content = request.POST['content'] from hellodb import model msg = model.Msg() msg.content = content model.meta.Session.add(msg) model.meta.Session.commit() return "add %s ok..." % content
添加部分简单完成。获取 POST 文本框,然后初始化一个 Msg 对象(上面 model 里定义的)。
注意 add 之后,必须手动 commit,这样才会真正保存到数据库。
浏览器访问一下:http://127.0.0.1:5000/db/index,随意添加一点数据吧,这个时候你可以在 PostgreSQL 里查询已经数据已经加进来了。
下面在 index 方法传递一些值到模板,输出刚才已经添加的数据:
def index(self): from hellodb import model c.msgs = model.meta.Session.query(model.Msg).all() return render('/db.htm')
c.msgs 可以理解成全局变量,关于 c 的定义在 controller前几行就应该看到了。修改模板 db.htm 显示记录:
% for msg in c.msgs:<p>${msg.id}: ${msg.content} / ${msg.addtime}</p>% endfor
很简单,只是一个普通 for 循环,遍历 index 方式里传递的 c.msgs。Mako模板还是很易读的吧?
继续刷新下:http://127.0.0.1:5000/db/index,可以在页面上看到已经添加的数据了。
在狂输入了几十条之后,在一页里显示是不是忒土鳖了?
下面再介绍下 Pylons 里 webhelper 里一个分页组件的用法,当然你也可以自己写分页算法。下面是示例:
def list(self): from webhelpers import paginate from hellodb import model msgs = model.meta.Session.query(model.Msg) c.paginator = paginate.Page( msgs, page=int(request.params.get('page', 1)), items_per_page = 10, ) return render("/list.htm")
导入 paginate,然后把查询的数据库对象当参数传递给 paginate.Page,里面的page则是页面的传递的页数参数,items_per_page 就好理解多了,就是多少条一页。这里是10条。
对应的模板 list.htm 如下:
<pre>% if len(c.paginator):% for msg in c.paginator:<p>${msg.id}: ${msg.content}</p>% endfor<p> ${c.paginator.pager("count: $item_count $first_item to $last_item , $link_first $link_previous $link_next $link_last")} </p>% endif
for 部分如同上面示例,下面加了一行pager。里面一些变量从名字上就可以看出功能了。包括了总条数、当前是第几到第几条,然后就是常用的首页、上页、下页和最后一页。
这里链接的文字都是<<, <, >, >>。想改成文字请查看文档吧。。如果是第一页,是不会显示首页和上一页的。这个做过分页的一般都写过类似的代码吧。
现在访问:http://127.0.0.1:5000/db/list,想看到效果当然你得多填点数据哦。10条才会显示分页的挖。
好了,这里对数据库增加和显示部分都已经有示例代码了,当然最后还有一个分页用法。至于删除和更新之类请参考 SQLAlchemy 文档吧。
http://chenxiaoyu.org/blog/archives/312
- Pylons 入门实例教程 – 数据库操作
- Pylons 入门实例教程 – Hello
- Pylons 入门实例教程 – cookie 和 session
- Pylons 入门实例教程 – 发布应用
- Pylons 入门实例教程 – 表单和文件上传
- Pylons架构网站开发入门实例教程
- Spring集成JDBC操作数据库实例教程
- pylons模板引擎Mako的快速入门
- Spring Batch入门实例教程实现对CVS文件的操作
- ActiveMQ实例教程--入门级别
- Omnet++ 4.0 入门实例教程
- React 入门实例教程
- 干货!React入门实例教程
- React入门实例教程 | 干货
- React 入门实例教程
- React 入门实例教程总结
- React 入门实例教程
- React 入门实例教程
- 解决RealPlayer11崩溃的问题
- 现代软件工程系列 学生读后感 梦断代码 DTSlob (1)
- Pylons 入门实例教程 – Hello
- 吐血整理 Delphi系列书籍 118本(全)
- Pylons 入门实例教程 – 表单和文件上传
- Pylons 入门实例教程 – 数据库操作
- 现代软件工程系列 学生读后感 梦断代码 DTSlob (2)
- C++学习1
- Socket错误
- Pylons 入门实例教程 – cookie 和 session
- 一致性hash算法 - consistent hashin
- Pylons 入门实例教程 – 发布应用
- web.py 数据库操作指南
- memcache的分布式缓存问题