Pylons 是 Python 的一个轻量级 MVC Web 开发框架,跟另外一个框架 TurboGears 比较相似,都是集合了一些优秀的组件而成。比如对 Request URL 采用了 Route,Template 采用了 Mako,数据库层则采用了ORM SQLAlchemy,当然,这些组件只是默认,你还可以根据自己喜好来选择其他组件,比如你可以采用 Jinja2 或 Genshi 模板,ORM也可以采用 SQLObject。完全是自由组合。
废话少说,现在开始安装吧。
smallfish@debian:~$ sudo aptitude install python-pylons
Debian/Ubuntu 系列系统可以直接 aptitude 安装,当然你也可以使用 easy_install 或者源码安装。
smallfish@debian:~$ sudo easy_install Pylons
更多安装文档请参考官网安装部分,http://pylonshq.com/docs/en/1.0/gettingstarted/#installing
好了,安装结束,来一个经典的Hello程序吧。
smallfish@debian:~/workspace/python$ paster create -t pylons hello Selected and implied templates: Pylons#pylons Pylons application template Variables: egg: hello package: hello project: hello Enter template_engine (mako/genshi/jinja2/etc: Template language) ['mako']: Enter sqlalchemy (True/False: Include SQLAlchemy 0.5 configuration) [False]: Creating template pylons Creating directory ./hello
下面输出略过,大致解说一下。Pylons 程序可以用 Paste 自动生成一些代码,包括controller。还可以运行 HTTP 服务来测试。
-t 表示自动创建的模板,可以如下来查看有哪些选项,更多就参考 help 吧。
smallfish@debian:~/workspace/python/hello$ paster create --list-templates Available templates: basic_package: A basic setuptools-enabled package paste_deploy: A web application deployed through paste.deploy pylons: Pylons application template pylons_minimal: Pylons minimal application template
看一下hello的目录结构:
smallfish@debian:~/workspace/python/hello$ ls development.ini ez_setup.py hello.egg-info README.txt setup.py docs hello MANIFEST.in setup.cfg test.ini
这里具体各个文件意思就不讲解了,程序主体部分都在hello/hello目录下,development.ini 和 test.ini 分别是服务启动的配置文件,用于测试和开发环境。开始先运行一下,看效果吧。。
smallfish@debian:~/workspace/python/hello$ paster serve --reload development.ini Starting subprocess with file monitor Starting server in PID 1519. serving on http://127.0.0.1:5000
在浏览器中打开:http://127.0.0.1:5000 看到页面了吧?恭喜。
继续,写一个简单的显示 hi的 controller 程序吧。
smallfish@debian:~/workspace/python/hello$ paster controller hi Creating /home/smallfish/workspace/python/hello/hello/controllers/hi.py Creating /home/smallfish/workspace/python/hello/hello/tests/functional/test_hi.py
自动生成程序和 test 文件。paster 启动服务不需要重启会自动加载,可以浏览器访问:http://127.0.0.1:5000/hi/index
很简单吧,打开 hi.py,基本如下:
class HiController(BaseController): def index(self): # Return a rendered template #return render('/hi.mako') # or, return a response return 'Hello World'
上面注释部分可以 return 一个模板文件,模板放入 templates 目录下即可。
去除上面的 return ‘Hello’ 返回 return render(‘/hi.mako’)
smallfish@debian:~/workspace/python/hello$ vi hello/templates/hi.mako % for key, value in request.environ.items(): ${key} = ${value} % endfor
刷新 http://127.0.0.1:5000/hi/index ,可以看到一些环境变量的输出了吧。
今天就简单的说到这里吧,下回来一个完整的例子,包括URL、模板、数据库和Session的实例。
COPY 命令可以快速的导入数据到 PostgreSQL 中,文件格式类似CVS之类。适合批量导入数据,比 \i 和恢复数据表快。
导出表数据到文件或 STDOUT :
COPY tablename [(column [, ...])] TO {'filename' | STDOUT} [[WITH] [BINARY] [OIDS] [DELIMITER [AS] 'delimiter'] [NULL [AS] 'null string'] [CSV [HEADER] [QUOTE [AS] 'quote'] [ESCAPE [AS] 'escape'] [FORCE NOT NULL column [, ...]]
导入文件或者 STDIN 到表中:
COPY tablename [(column [, ...])] FROM {'filename' | STDIN} [[WITH] [BINARY] [OIDS] [DELIMITER [AS] 'delimiter'] [NULL [AS] 'null string'] [CSV [HEADER] [QUOTE [AS] 'quote'] [ESCAPE [AS] 'escape'] [FORCE QUOTE column [, ...]]
导出表 employee 到默认输出 STDOUT:
psql> COPY employee TO STDOUT; 1 JG100011 Jason Gilmore [email protected] 2 RT435234 Robert Treat [email protected] 3 GS998909 Greg Sabino Mullane [email protected] 4 MW777983 Matt Wade [email protected]
导出表 employee 到 sql 文件:
psql> COPY employee TO '/home/smallfish/employee.sql';
从文件导入数据:
psql> COPY employeenew FROM '/home/smallfish/employee.sql'; psql> SELECT * FROM employeenew; employeeid | employeecode | name | email ------------+--------------+---------------------+--------------- 1 | JG100011 | Jason Gilmore | [email protected] 2 | RT435234 | Robert Treat | [email protected] 3 | GS998909 | Greg Sabino Mullane | [email protected] 4 | MW777983 | Matt Wade | [email protected] (4 rows)
输出对象ID(OIDS):
psql> COPY employee TO STDOUT OIDS; 24627 1 GM100011 Jason Gilmore [email protected] 24628 2 RT435234 Robert Treat [email protected] 24629 3 GS998909 Greg Sabino Mullane [email protected] 24630 4 MW777983 Matt Wade [email protected]
指定导出间隔符,默认是 \t ,这里为 | :
psql>COPY employee TO STDOUT DELIMITER '|'; 1|GM100011|Jason Gilmore|[email protected] 2|RT435234|Robert Treat|[email protected] 3|GS998909|Greg Sabino Mullane|[email protected] 4|MW777983|Matt Wade|[email protected]
导入文件数据,指定间隔符为 | :
psql> COPY employeenew FROM '/home/smallfish/employee.sql' DELIMITER |;
导出指定字段的数据:
psql> COPY employee (name,email) TO STDOUT; Jason Gilmore [email protected] Robert Treat [email protected] Greg Sabino Mullane [email protected] Matt Wade [email protected]
为 NULL 字段设置默认值:
psql> COPY employee TO STDOUT NULL 'no email'; Jason Gilmore no email Robert Treat [email protected] Greg Sabino Mullane [email protected] Matt Wade no email
导出为CVS格式:
psql> COPY employee (name, email) TO '/home/smallfish/employee.csv' CSV HEADER;
参考资料:Apress Beginning PHP and PostgreSQL 8: From Novice to Professional
文档地址:http://golang.org/cmd/goinstall/ Go模块列表:http://godashboard.appspot.com/package
goinstall 主要是方便安装第三方模块,目前支持 hg(mercurial),git,svn三种版本控制系统。
下面来举例怎么安装 web.go 模块。源地址是:http://github.com/hoisie/web.go
smallfish@debian:~$ goinstall -dashboard=true github.com/hoisie/web.go
根据网速快慢,过一段时间会结束。期间木有任何提示。(可以加上 -v=true 参数,可以显示安装过程和提示。)
查看下安装的目录和路径:
smallfish@debian:~$ ls $GOROOT/src/pkg/github.com/hoisie/web.go/ examples _go_.8 Makefile Readme.md scgi.go status.go web_test.go fcgi.go LICENSE _obj request.go servefile.go web.go
代码示例:
import (web "github.com/hoisie/web.go")
另外注意点,官方文档里 -update 选项现在版本里已经缩写,改成 -u。
一般情况完全可以在 Python 里导入 from math import sin 然后调用 sin() 函数。然而,调用C里面的 sin() 函数速度会更快,尤其在复杂的循环里。在 Cython 里可以这样声明和使用:
cdef extern from "math.h": double sin(double) cdef double f(double x): return sin(x*x)
请注意,上面的代码声明了 math.h 里的函数,提供给 Cython 使用。C编译器在编译时将会看到 math.h 的声明,但 Cython 不会去分析 math.h 和单独的定义。
当调用一个C函数时,一定要注意引入适当的链接库。这个依赖于特定的平台;下面的例子可以在Linux和Mac OS X下运行:
from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_modules=[ Extension("demo", ["demo.pyx"], libraries=["m"]) # Unix-like specific ] setup( name = "Demos", cmdclass = {"build_ext": build_ext}, ext_modules = ext_modules )
跟从 math 库里使用 sin() 函数一样,它可以声明和导入任何C库,Cython会生成正确的共享或者静态链接库。
注:此文系纯水贴,正经人士请绕道。
场景1
某日很HI的写着程序,凑巧做网页的美工不在,活又耽误不得,只能捋起袖子,装起了Dreamweaver+Fireworks,三下五除二搞定了前端页面。话说自从开始写程序起,就很少碰这些高级玩意了。现在只是偶尔PS修修抠抠图,享受下钢笔抠图小YY一把就足够了。
其实在做程序之前,俺一直是个美工,作图做页面只不过信手拈来。
场景2
简历给某朋友看了之后,很惊讶道:原来你是做Java的?只好含泪不语+内流满面了。难道我博客只写Python或者Perl,不意味着俺就是折腾这些的哇。只好幽幽的坦然回答之:其实我的主业是Java开发者,做了六年多。
其实动态语言只是我的业余爱好,顺带写了点分享的博文而已。只不过对外闭口没提Java。
场景3
有些朋友看我经常推荐PostgreSQL,就问俺:Pg和MySQL到底有哪些区别?描述种种,感觉可能他也云里雾里。遂让他自己说说需求,最后还是推荐他用MySQL。顺带讲述了一些常用优化和监控的办法。丫又惊讶的说原来你一直用的MySQL啊。好吧,只好再次内流。
其实我正儿八经用数据库最长久的就是MySQL了,基本也有六年多了把。Pg只是我的业余爱好,没事研究了下,寻找下乐趣而已。
如此场景会继续重现,遂略过数字。。。
其实,我就是个演员。对系统(Linux)、语言(Java/Python/Perl)、数据库(MySQL/PostgreSQL)都略懂的角色。
不同的时间,演绎不同的角色。过去是,现在是,将来也是。
Virtual Box 是个不错的虚拟机,小巧,功能也齐全。好像有点推销鸟。说正题,上次有个朋友就提到怎么能主机里访问虚拟机里的服务,昨晚实验了下,颇为顺利。记录下。这里利用的是默认的NAT上网,也就是共享主机上网,而不是设置独立的IP。
主机:Win XP
虚拟:Ubuntu 9.10
目的:Win里ssh进Ubuntu,能访问里面提供的服务。
主要是通过 VBoxManage setextradata 设置一些属性。
先上几个步骤图把。注意一下修改,先得关闭虚拟机,修改完事以后再启动。
1. 查看虚拟机中的名称:ubuntu9
2. 进入本机Vbox目录,运行VBoxManage,查看下。
下面的pcnet是vbox里的网络设置,0是表示第一个网卡,后面一次类推。22是ssh端口,映射到主机的22端口。
VBoxManage setextradata "ubuntu9" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/Protocol" TCP VBoxManage setextradata "ubuntu9" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/GuestPort" 22 VBoxManage setextradata "ubuntu9" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/HostPort" 22
5. 启动虚拟机。
6. 设置putty登陆之。
到这里已经顺利ssh 到127.0.0.1,如果想访问虚拟机里的web服务器呢?同样很简单。
只要如下设置,web端口为81,跟上面也雷同:
VBoxManage setextradata "ubuntu9" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/web/Protocol" TCP VBoxManage setextradata "ubuntu9" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/web/GuestPort" 81 VBoxManage setextradata "ubuntu9" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/web/HostPort" 81
另外如果想清空上面设置的选项,只要不设置后面的值即可:
VBoxManage setextradata "ubuntu9" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/web/Protocol"
原文参见:http://www.mongodb.org/display/DOCS/Tutorial
启动数据库
下载 MongoDB, 解压后并启动:
$ bin/mongod
MongoDB 默认存储数据目录为 /data/db/ (或者 c:\data\db), 当然你也可以修改成不同目录, 只需要指定 –dbpath 参数:
$ bin/mongod --dbpath /path/to/my/data/dir
获取数据库连接
现在我们就可以使用自带的shell工具来操作数据库了. (我们也可以使用各种编程语言的驱动来使用MongoDB, 自带的shell工具可以方便我们管理数据库)
启动 MongoDB JavaScript 工具:
$ bin/mongo
默认 shell 连接的是本机localhost 上面的 test库, 会看到:
MongoDB shell version: 0.9.8 url: test connecting to: test type "help" for help >
“connecting to:” 这个会显示你正在使用的数据库的名称. 想换数据库的话可以:
> use mydb
可以输入 help 来查看所有的命令.
插入数据到集合
下面我们来建立一个test的集合并写入一些数据. 建立两个对象, j 和 t , 并保存到集合中去.
在例子里 ‘>’ 来表示是 shell 输入提示符
> j = { name : "mongo" }; {"name" : "mongo"} > t = { x : 3 }; { "x" : 3 } > db.things.save(j); > db.things.save(t); > db.things.find(); {"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")} {"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")} >
有几点需要注意下 :
- 不需要预先建立一个集合. 在第一次插入数据时候会自动建立.
- 在例子其实可以存储任何结构的数据, 当然在实际应用我们存储的还是相同元素的集合. 这个特性其实可以在应用里很灵活, 你不需要类似 alter table 来修改你的数据结构
- 每次插入数据时候对象都会有一个ID, 名字叫 _id.
当你运行不同的例子, 你的对象ID值都是不同的.
下面再加点数据:
> for( var i = 1; i < 10; i++ ) db.things.save( { x:4, j:i } ); > db.things.find(); {"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")} {"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")} {"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")} {"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")} {"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")} {"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")} {"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")} {"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")} {"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")} {"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}
请注意下, 这里循环次数是10, 但是只显示到8, 还有2条数据没有显示.
如果想继续查询下面的数据只需要使用 it 命令, 就会继续下面的数据:
{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")} {"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}
继续
> it {"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")} {"x" : 4 , "j" : 10 , "_id" : ObjectId("497cf87151712cf7758fbdc6")}
从技术上讲 find() 返回一个游标对象. 但在上面的例子里, 并没有拿到一个游标的变量. 所以 shell 自动遍历游标, 返回一个初始化的set, 并允许我们继续用 it 迭代输出.
当然我们也可以直接用游标来输出, 不过这个是下一部分的内容了.
查询数据
在没有深入查询之前, 我们先看看怎么从一个查询中返回一个游标对象. 可以简单的通过 find() 来查询, 他返回一个任意结构的集合. 如果实现特定的查询稍后讲解.
实现上面同样的查询, 然后通过 while 来输出:
> var cursor = db.things.find(); > while (cursor.hasNext()) { print(tojson(cursor.next())); } {"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")} {"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")} {"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")} {"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")} {"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")} {"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")} {"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")} {"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")} {"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")} {"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")} {"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")} >
上面的例子显示了游标风格的迭代输出. hasNext() 函数告诉我们是否还有数据, 如果有则可以调用 next() 函数. 这里我们也用了自带的 tojson() 方法返回一个标准的 JSON 格式数据.
当我们使用的是 JavaScript shell, 可以用到JS的特性, forEach 就可以输出游标了. 下面的例子就是使用 forEach() 来循环输出:
> db.things.find().forEach( function(x) { print(tojson(x));}); {"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")} {"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")} {"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")} {"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")} {"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")} {"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")} {"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")} {"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")} {"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")} {"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")} {"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")} >
forEach() 必须定义一个函数供每个游标元素调用.
在 mongo shell 里, 我们也可以把游标当作数组来用 :
> var cursor = db.things.find(); > print (tojson(cursor[4])); {"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}
使用游标时候请注意占用内存的问题, 特别是很大的游标对象, 有可能会内存溢出. 所以应该用迭代的方式来输出.
下面的示例则是把游标转换成真实的数组类型:
> var arr = db.things.find().toArray(); > arr[5]; {"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}
请注意这些特性只是在 mongo shell 里使用, 而不是所有的其他应用程序驱动都支持.
MongoDB 游标对象不是没有快照 – 如果有其他用户在集合里第一次或者最后一次调用 next(), 你可以得不到游标里的数据. 所以要明确的锁定你要查询的游标.
指定条件的查询
到这里我们已经知道怎么从游标里实现一个查询并返回数据对象, 下面就来看看怎么根据指定的条件来查询.
下面的示例就是说明如何执行一个类似SQL的查询, 并演示了怎么在 MongoDB 里实现. 这是在 MongoDB shell 里查询, 当然你也可以用其他的应用驱动或者语言来实现:
SELECT * FROM things WHERE name="mongo"
> db.things.find({name:"mongo"}).forEach(function(x) { print(tojson(x));}); {"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")} >
SELECT * FROM things WHERE x=4
> db.things.find({x:4}).forEach(function(x) { print(tojson(x));}); {"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")} {"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")} {"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")} {"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")} {"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")} {"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")} {"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")} {"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")} {"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")} >
查询条件是 { a:A, b:B, … } 类似 “where a==A and b==B and …”, 更多的查询方式可以参考 Mongo 开发教程部分.
上面显示的是所有的元素, 当然我们也可以返回特定的元素, 类似于返回表里某字段的值, 只需要在 find({x:4}) 里指定元素的名字, 比如 j:
SELECT j FROM things WHERE x=4
> db.things.find({x:4}, {j:true}).forEach(function(x) { print(tojson(x));}); {"j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")} {"j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")} {"j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")} {"j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")} {"j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")} {"j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")} {"j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")} {"j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")} {"j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")} >
请注意 “_id” 元素会一直被返回.
findOne() – 语法糖
为了方便, mongo shell (其他驱动) 避免游标的可能带来的开销, 提供一个findOne() 函数. 这个函数和 find() 参数一样, 不过他返回游标里第一条数据, 或者返回 null 空数据库.
作为一个例子, name==’mongo’ 可以用很多方法来实现, 可以用 next() 来循环游标(需要校验是否为null), 或者当做数组返回第一个元素.
但是用 findOne() 方法则更简单和高效:
> var mongo = db.things.findOne({name:"mongo"}); > print(tojson(mongo)); {"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")} >
findOne 方法更跟 find({name:”mongo”}).limit(1) 一样.
limit() 查询
你可以需要限制结果集的长度, 可以调用 limit 方法.
这是强烈推荐高性能的原因, 通过限制条数来减少网络传输, 例如:
> db.things.find().limit(3); in cursor for : DBQuery: example.things -> {"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")} {"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")} {"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")} >
更多帮助
除非了一般的 help 之外, 你还可以查询 help 数据库和db.whatever 来查询具体的说明.
如果你对一个函数要做什么, 你可以不输入 {{()}} 这些结束的括号则可以输出实现的源码, 例如:
> db.foo.insert function (obj, _allow_dot) { if (!obj) { throw "no object passed to insert!"; } if (!_allow_dot) { this._validateForStorage(obj); } return this._mongo.insert(this._fullName, obj); }
mongo 是一个完整的 JavaScript shell程序, 所以在 shell 里完全可以私用JS的方法、类、语法. 此外, MongoDB 定义很多自己的类和全局变量 (比如 db). 这里可以查看完整的API说明 http://api.mongodb.org/js/.
接下来
看完这篇教程后下一步则看MongoDB更详细的文档 http://www.mongodb.org/display/DOCS/Manual
默认的ConfigParser对于选项是按照字母顺序排列的。如下代码:
>>> from ConfigParser import ConfigParser >>> cf = ConfigParser() >>> cf.add_section('d') >>> cf.set('d', 'name', 'smallfish') >>> cf.add_section('a') >>> cf.set('a', 'name', 'smallfish2') >>> cf.write(open('d:/a.ini', 'w')) >>> cf = None
生成配置如下:
[a] name = smallfish2 [d] name = smallfish
翻阅了官方文档似乎对ConfigParser中section的顺序没啥解说,毕竟字典本身就是无序的,如果想修改估计只能从源码入手把。不过有一个ConfigObj库还不错,可以实现顺序,当然功能不仅仅如此啦。下载地址:http://www.voidspace.org.uk/python/configobj.html
代码片段如下:
>>> from configobj import ConfigObj >>> config = ConfigObj() >>> config.filename = 'd:/a.ini' >>> config['d'] = {} >>> config['d']['name'] = 'smallfish' >>> config['a'] = {} >>> config['a']['name'] = 'smallfish2' >>> config.write()
生成配置如下:
[d] name = smallfish [a] name = smallfish2
经过几天的适应总算在杭州安定下来了,回归到简单而快乐的上班生活轨道上。
夜深人静的时侯才能静下心来写点关于自己的话题,不再浮躁。
回想这毕业后的六年多的时间,自己都在做些什么?工作的内容在不停的变化,唯一不变的就是坚持了自己的梦想,一个小小的技术梦想。梦想只是目标,而坚持应该是梦想的过程。结果不一定很绚烂,但过程一定要精彩。
第一份工作真的很稚嫩,从文科啥也不懂,菜鸟起步,做起了Web设计和简单的程序编写。当然起步都是需要点时间和积累的。现在还记得为自己做出一个个简单的动画效果而激动无比的场景。随着时间的推移,发觉自己在创意方面的缺乏,两年之后就离开了生活的那个城市。
第二份工作时间很长,四年半的时间。算是一个正规军把 只不过后来也变得有点山寨。收获最大的就是伴随着公司的发展对技术的不断提高要求,接触的很越来越多。最初那种土鳖式的代码工已经不符合了。逐步了解了分层模式,框架,服务器,数据库等等很多有趣的东西。而不仅仅的是把代码写完就完事了。技术上面的提高,当然也带来视野上的扩展。从开始的单一语言发展到后来的多语言结合,单一的数据库到几十台的主从结构,数据应用的分离,数据的切分,缓存系统的应用,以及服务器模块的开发。现在还记得某年的夏天没有空调一帮人赤膊写代码的场景,多hi阿。回想起过去的种种,内心真的难以平静。有时侯想想真的不是想离开,有点无奈。
最近踏上了新的起点,六年以后的第三份工作:淘宝。最初喜欢上淘宝是因为看到的网上办公环境照片,通过一些朋友的了解,里面的武侠文化很吸引自己,想想自己曾经也疯狂迷恋过武侠小说,导致正经的文学没学几篇,很是遗憾阿。经过这几天的初步接触,每天都会有着不同的收获。虽然从事的工作跟过去的内容和岗位都不太一样,但是正因为如此才有更多的好奇与向往。
一直相信只要有坚持,就会有梦想。而不是倒过来,本子电也不多了,洗洗睡吧。祝自己好运,good night!
Nginx本身可以通过
kill -HUP `cat /usr/local/nginx/logs/nginx.pid`
进行平滑重启的,可以通过ps进程查看一下。效果还是挺不错的。
这里介绍的是另外一种方式service,适合RHEL/CentOS系列。
1. kill nginx进程
kill `cat /usr/local/nginx/logs/nginx.pid`
2. 建立 /etc/init.d/nginx 文件
#!/bin/sh # # nginx - this script starts and stops the nginx daemin # # chkconfig: - 85 15 # description: Nginx is an HTTP(S) server, HTTP(S) reverse \ # proxy and IMAP/POP3 proxy server # processname: nginx # config: /usr/local/nginx/conf/nginx.conf # pidfile: /usr/local/nginx/logs/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 nginx="/usr/local/nginx/sbin/nginx" prog=$(basename $nginx) NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf" lockfile=/var/lock/subsys/nginx start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 echo -n $"Starting $prog: " daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { configtest || return $? stop start } reload() { configtest || return $? echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2 esac
3. 设置脚本为可执行
chmod +x /etc/init.d/nginx
4.
/sbin/chkconfig nginx on
5. 检查下
/sbin/chkconfig --list nginx nginx 0:off 1:off 2:on 3:on 4:on 5:on 6:off
完成咯~可以尝试下面方式启动或者重启
service nginx start service nginx stop service nginx restart service nginx reload /etc/init.d/nginx start /etc/init.d/nginx stop /etc/init.d/nginx restart /etc/init.d/nginx reload