<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>smallfish logs</title>
	<atom:link href="http://chenxiaoyu.org/feed" rel="self" type="application/rss+xml" />
	<link>http://chenxiaoyu.org</link>
	<description>关注 Python &#38; Go &#38; PostgreSQL</description>
	<lastBuildDate>Sat, 03 Jul 2010 16:15:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Pylons 入门实例教程 – cookie 和 session</title>
		<link>http://chenxiaoyu.org/blog/archives/327</link>
		<comments>http://chenxiaoyu.org/blog/archives/327#comments</comments>
		<pubDate>Sat, 03 Jul 2010 12:38:58 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Pylons]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/?p=327</guid>
		<description><![CDATA[本篇讲述在 Pylons 里使用 cookie 和 session。
示例还是在上篇《Pylons 入门实例教程 &#8211; 数据库操作》的代码里继续添加。先来尝试下  cookie，添加新的 cookietest controller。
修改 index 方法，添加显示部分：
    def index(self):
        name = 'NULL'
        if request.cookies.has_key('name'):
            name = request.cookies['name']
    [...]]]></description>
			<content:encoded><![CDATA[<p>本篇讲述在 Pylons 里使用 cookie 和 session。</p>
<p>示例还是在上篇《<a href="http://chenxiaoyu.org/blog/archives/312" target="_blank">Pylons 入门实例教程 &#8211; 数据库操作</a>》的代码里继续添加。先来尝试下  cookie，添加新的 cookietest controller。</p>
<p>修改 index 方法，添加显示部分：</p>
<pre>    def index(self):
        name = 'NULL'
        if request.cookies.has_key('name'):
            name = request.cookies['name']
        return 'cookie name=%s' % name</pre>
<p>cookie 读取可以通过 request.cookies 对象，类似一个字典结构。需要注意的是读取时候用最好 has_key 判断下，这样避免抛 KeyError 异常。当然你也可以 try&#8230;catch 捕获一下。</p>
<p>再重新写一个方法，用来写 cookie。</p>
<pre>    def writecookie(self):
        response.set_cookie("name", "smallfish")
        return "write cookie ok"</pre>
<p>这里只是简单设置一个值得，set_cookie 还有其他参数，具体如下：</p>
<pre>set_cookie(self, key, value='', max_age=None, path='/', domain=None, secure=None,
                 httponly=False, version=None, comment=None, expires=None, overwrite=False)</pre>
<p>基本一般需要设置：max_age，path，domain，expires 这几个参数。</p>
<p>下面再来尝试一下 session：</p>
<pre>smallfish@debian:~/workspace/python/hellodb$ paster controller sessiontest
Creating /home/smallfish/workspace/python/hellodb/hellodb/controllers/sessiontest.py
Creating /home/smallfish/workspace/python/hellodb/hellodb/tests/functional/test_sessiontest.py</pre>
<p>和上面 cookie 例子类似，在 controller 里有两个方法，index 负责显示 session，writesession 负责写。</p>
<pre>    def index(self):
        name = session.get('name', 'NULL')
        return 'session name=%s' % name

    def writesession(self):
        session['name'] = 'smallfish'
        session.save()
        return "save session ok"</pre>
<p>index 方法里 get 后面的 NULL 是默认值。writesession 里需要注意下设置 session 之后需要 save。</p>
<p>删除 session 可以尝试如下：</p>
<pre>del session['name']
# 删除所有
session.delete()</pre>
<p>到这里，WEB 常用的一些东西在 Pylons 里基本走了一圈，包含 URL、模板、数据库和会话部分。</p>
<p>下一节将会涉及怎么在 Nginx 上发布 Pylons 应用。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/327">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/327#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/327&title=Pylons 入门实例教程 – cookie 和 session">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/pylons" rel="tag">Pylons</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/327/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Pylons 入门实例教程 – 数据库操作</title>
		<link>http://chenxiaoyu.org/blog/archives/312</link>
		<comments>http://chenxiaoyu.org/blog/archives/312#comments</comments>
		<pubDate>Thu, 01 Jul 2010 12:43:01 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Pylons]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/?p=312</guid>
		<description><![CDATA[前面两篇入门，讲述了 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 postgres
postgres@debian:/home/smallfish/workspace/python/hello$ createdb -O smallfish test
postgres@debian:/home/smallfish/workspace/python/hello$ exit
smallfish@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 [...]]]></description>
			<content:encoded><![CDATA[<p>前面两篇入门，讲述了 Pylons 大致开发的流程、表单以及文件上传，思路大致跟传统的开发类似。本篇简单讲述下在 Pylons 如何使用数据库。</p>
<p>本篇侧重点是使用 ORM 框架 <a href="http://www.sqlalchemy.org/" target="_blank">SQLAlchemy</a>。现在 Python 社区里关注度比较高的大概有三：<a href="http://www.sqlalchemy.org/" target="_blank">SQLAlchemy</a>、<a href="http://www.sqlobject.org/" target="_blank">SQLObject</a> 和 <a href="https://storm.canonical.com/" target="_blank">Storm</a>。其实本人最早是研究了一下 Storm，后来听虾哥（@marchliu）在应用里不是很爽之，遂关注了下他推荐的 SQLAlchemy。当然，你也可以对应数据库的 DB-API 库来进行操作。</p>
<p>示例代码的数据库是 <a href="http://www.postgresql.org" target="_blank">PostgreSQL</a>，对应的 Python 库使用的是 <a href="http://initd.org/projects/ " target="_blank">psycopg2</a>。至于 Pg 配置和使用这里不再累赘，请狗之。</p>
<p>Debian/Ubuntu 安装很简单：</p>
<pre>sudo aptitude install python-psycopg2</pre>
<p>建立一个测试数据库，比如 test：</p>
<pre>smallfish@debian:~/workspace/python/hello$ su postgres
postgres@debian:/home/smallfish/workspace/python/hello$ createdb -O smallfish test
postgres@debian:/home/smallfish/workspace/python/hello$ exit
smallfish@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=#</pre>
<p>数据库的部分已经OK，下面就是来倒腾 Pylons 啦。</p>
<p>建立新项目，加入支持数据库部分，注意 Enter sqlalchemy那个选项，默认是 False，改成 True：</p>
<pre>smallfish@debian:~/workspace/python$ paster create -t pylons hellodb
Selected and implied templates:
  Pylons#pylons  Pylons application template

Variables:
  egg:      hellodb
  package:  hellodb
  project:  hellodb
Enter template_engine (mako/genshi/jinja2/etc: Template language) ['mako']:
Enter sqlalchemy (True/False: Include SQLAlchemy 0.5 configuration) [False]: True
Creating template pylons
Creating directory ./hellodb</pre>
<p>改成 True 之后在自动生成的 development.ini 里就有对应的数据库配置选项了。</p>
<p>再建立新的 db controller：</p>
<pre>smallfish@debian:~/workspace/python$ cd hellodb/
smallfish@debian:~/workspace/python/hellodb$ paster controller db
Creating /home/smallfish/workspace/python/hellodb/hellodb/controllers/db.py
Creating /home/smallfish/workspace/python/hellodb/hellodb/tests/functional/test_db.py</pre>
<p>编辑 development.ini，添加数据库配置部分。smallfish:123456 是对应的 PostgreSQL 用户名/密码，127.0.0.1:5432 是对应的主机地址/端口号，最后的test则是数据库名。</p>
<pre># SQLAlchemy database URL
sqlalchemy.url = postgresql://smallfish:123456@127.0.0.1:5432/test</pre>
<p>编辑 hellodb/model/__init__.py，加上一个叫 msg 的表和字段的定义：</p>
<pre>"""The application's model objects"""
from hellodb.model.meta import Session, metadata

from sqlalchemy import orm, schema, types
from datetime import datetime

def 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):
    pass

orm.mapper(Msg, msg_table)</pre>
<p>示例 Msg 表很简单，三个字段：ID、内容和时间。</p>
<p>上面的代码除去导入 sqlclchemy 包里几个库，基本上有一个对应表的字段定义，还有一个空的 Msg 对象。</p>
<p>最后一行，则是做一个 map 的动作，把 Msg 映射到 msg_table 上。</p>
<p>下面是不是要在数据库里建立对应的表呢？有个简单的办法 可以初始化数据库：paster setup-app development.ini：</p>
<pre>smallfish@debian:~/workspace/python/hellodb$ paster setup-app development.ini
Running setup_config() from hellodb.websetup
20: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)s
20: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</pre>
<p>可以看到上面的输出日志，包括了建表的SQL语句。其中 SERIAL 对应上面 __init__.py 里 Column 的 Seq 定义。serial 类型 在 PostgreSQL 可以看成类似 MySQL 的自增ID（auto_increment） 。</p>
<p>现在进入 PostgreSQL 查询数据库，就可以看到表以及序列已经建立。</p>
<pre>test=# \d
                  关联列表
 架构模式 |    名称    |  型别  |  拥有者
----------+------------+--------+-----------
 public   | msg        | 资料表 | smallfish
 public   | msg_id_seq | 序列数 | smallfish
(2 行记录)</pre>
<p>到这里，准备工作已经完毕，包括了初始化数据库，配置文件还有示例 controller。</p>
<p>下面就在 controller 代码里增加读写数据库的功能吧。</p>
<p>首先建立一个表单模板 db.htm ，用来添加并保存到数据库表中：</p>
<pre>&lt;form action="/db/add" method="post"&gt;
    &lt;input type="text" name="content" /&gt;
    &lt;br /&gt;
    &lt;input type="submit" value="save" /&gt;
&lt;/form&gt;</pre>
<p>对应 controller index 修改成，很简单。返回到模板：</p>
<pre>class DbController(BaseController):

    def index(self):
        return render('/db.htm')</pre>
<p>添加 add 方法，对应上面 form 中的 /db/add 路径：</p>
<pre>    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</pre>
<p>添加部分简单完成。获取 POST 文本框，然后初始化一个 Msg 对象（上面 model 里定义的）。</p>
<p>注意 add 之后，必须手动 commit，这样才会真正保存到数据库。</p>
<p>浏览器访问一下：http://127.0.0.1:5000/db/index，随意添加一点数据吧，这个时候你可以在 PostgreSQL 里查询已经数据已经加进来了。</p>
<p>下面在 index 方法传递一些值到模板，输出刚才已经添加的数据：</p>
<pre>    def index(self):
        from hellodb import model
        c.msgs = model.meta.Session.query(model.Msg).all()
        return render('/db.htm')</pre>
<p>c.msgs 可以理解成全局变量，关于 c 的定义在 controller前几行就应该看到了。修改模板 db.htm 显示记录：</p>
<pre>% for msg in c.msgs:
&lt;p&gt;${msg.id}: ${msg.content} / ${msg.addtime}&lt;/p&gt;
% endfor</pre>
<p>很简单，只是一个普通 for 循环，遍历 index 方式里传递的 c.msgs。Mako模板还是很易读的吧？</p>
<p>继续刷新下：http://127.0.0.1:5000/db/index，可以在页面上看到已经添加的数据了。</p>
<p>在狂输入了几十条之后，在一页里显示是不是忒土鳖了？</p>
<p>下面再介绍下 Pylons 里 webhelper 里一个分页组件的用法，当然你也可以自己写分页算法。下面是示例：</p>
<pre>    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")</pre>
<p>导入 paginate，然后把查询的数据库对象当参数传递给 paginate.Page，里面的page则是页面的传递的页数参数，items_per_page 就好理解多了，就是多少条一页。这里是10条。</p>
<p>对应的模板 list.htm 如下：</p>
<pre>&lt;pre&gt;
% if len(c.paginator):

% for msg in c.paginator:
&lt;p&gt;${msg.id}: ${msg.content}&lt;/p&gt;
% endfor

&lt;p&gt; ${c.paginator.pager("count: $item_count $first_item to $last_item , $link_first $link_previous $link_next $link_last")} &lt;/p&gt;
% endif</pre>
<p>for 部分如同上面示例，下面加了一行pager。里面一些变量从名字上就可以看出功能了。包括了总条数、当前是第几到第几条，然后就是常用的首页、上页、下页和最后一页。</p>
<p>这里链接的文字都是&lt;&lt;， &lt;， &gt;， &gt;&gt;。想改成文字请查看文档吧。。如果是第一页，是不会显示首页和上一页的。这个做过分页的一般都写过类似的代码吧。</p>
<p>现在访问：http://127.0.0.1:5000/db/list，想看到效果当然你得多填点数据哦。10条才会显示分页的挖。</p>
<p>好了，这里对数据库增加和显示部分都已经有示例代码了，当然最后还有一个分页用法。至于删除和更新之类请参考 SQLAlchemy 文档吧。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/312">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/312#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/312&title=Pylons 入门实例教程 – 数据库操作">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/pylons" rel="tag">Pylons</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/312/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pylons 入门实例教程 – 表单和文件上传</title>
		<link>http://chenxiaoyu.org/blog/archives/306</link>
		<comments>http://chenxiaoyu.org/blog/archives/306#comments</comments>
		<pubDate>Wed, 30 Jun 2010 12:19:56 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Pylons]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/?p=306</guid>
		<description><![CDATA[继续上一篇《Pylons 入门实例教程 &#8211; Hello》，现在开始讲在 Pylons 里如何提交表单和上传文件。
继续延用上篇里面的 hello 工程，在 HiController 里添加 form 方法：
    def form(self):
        return render('/form.mako')
加完以后可以访问：http://127.0.0.1:5000/hi/form，会报错。
Server Error，根据报错内容大致就知道模板文件不存在了。如果有其他错误，也可以通过这个页面查看，当然还有很强大的 Debug 个功能哦。当然正式环境一般都是关闭这个功能的。这个，你懂得。。。
好吧，写一个表单的模板，只包含一个简单的文本框和提交按钮示例。
&#60;form action="/hi/submit" method="post"&#62;
name: &#60;input type="text" name="name" /&#62;
&#60;br /&#62;
&#60;input type="submit" value="submit" /&#62;
&#60;/form&#62;
再添加一个 submit 方法来处理表单提交，
    def submit(self):
        return "hello, [...]]]></description>
			<content:encoded><![CDATA[<p>继续上一篇《<a href="http://chenxiaoyu.org/blog/archives/294" target="_blank">Pylons 入门实例教程 &#8211; Hello</a>》，现在开始讲在 Pylons 里如何提交表单和上传文件。</p>
<p>继续延用上篇里面的 hello 工程，在 HiController 里添加 form 方法：</p>
<pre>    def form(self):
        return render('/form.mako')</pre>
<p>加完以后可以访问：http://127.0.0.1:5000/hi/form，会报错。</p>
<p>Server Error，根据报错内容大致就知道模板文件不存在了。如果有其他错误，也可以通过这个页面查看，当然还有很强大的 Debug 个功能哦。当然正式环境一般都是关闭这个功能的。这个，你懂得。。。</p>
<p>好吧，写一个表单的模板，只包含一个简单的文本框和提交按钮示例。</p>
<pre>&lt;form action="/hi/submit" method="post"&gt;
name: &lt;input type="text" name="name" /&gt;
&lt;br /&gt;
&lt;input type="submit" value="submit" /&gt;
&lt;/form&gt;</pre>
<p>再添加一个 submit 方法来处理表单提交，</p>
<pre>    def submit(self):
        return "hello, name: %s" % request.params['name']</pre>
<p>request.params 包含了表单或者URL提交的参数，建议 POST 数据参照下面的上传部分。想获取更详细的列表，可以查看文档或者自己手动 dir()查阅。</p>
<p>下面尝试一下文件上传，首先在 development.ini 添加一个变量，用来存放文件上传后的文件夹。</p>
<pre>[app:main]
upload_dir = %(here)s/upload</pre>
<p>%(here) 启动后 server 会替换到当前目录地址，上面的地址就是当前路径下的upload文件夹。</p>
<p>修改一下刚才的表单，加一个 file 上传，注意 multipart/form-data 这句，上传必须。</p>
<pre>&lt;form action="/hi/submit" method="post"  enctype= "multipart/form-data"&gt;
name: &lt;input type="text" name="name" /&gt;
&lt;br /&gt;
file: &lt;input type="file" name="file" /&gt;
&lt;br /&gt;
&lt;input type="submit" value="submit" /&gt;
&lt;/form&gt;</pre>
<p>修改 submit 方法，添加文件内容：</p>
<pre>    def submit(self):
        name   = request.POST['name']
        myfile = request.POST['file']
        import os
        import shutil
        from pylons import config
        local_name = os.path.join(config['app_conf']['upload_dir'], myfile.filename)
        local_file = open(local_name, "wb")
        shutil.copyfileobj(myfile.file, local_file)
        myfile.file.close()
        local_file.close()
        return "hello, name: %s, upload: %s" % (name, myfile.filename)</pre>
<p>里面 import 部分这里仅仅为了示例，正式的代码请放入程序开头部分，POST 内容可以从 request.POST 获取。</p>
<p>config['app_conf']['upload_dir'] 就是刚才配置里 development.ini 定义的地址。这个目录需要自己手动创建哦。</p>
<pre>smallfish@debian:~/workspace/python/hello$ mkdir upload</pre>
<p>OK，到这里程序部分都已经修改完成。重新访问一下：http://127.0.0.1:5000/hi/form</p>
<p>尝试一下上传，上传后可以在 upload 文件夹下看到文件了吧。。</p>
<p>当然这里只是示例，还需要处理一下上传的名字，防止有特殊符号哦。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/306">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/306#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/306&title=Pylons 入门实例教程 – 表单和文件上传">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/pylons" rel="tag">Pylons</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/306/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>如何写 Go 代码？</title>
		<link>http://chenxiaoyu.org/blog/archives/297</link>
		<comments>http://chenxiaoyu.org/blog/archives/297#comments</comments>
		<pubDate>Tue, 29 Jun 2010 13:03:54 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Go]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/?p=297</guid>
		<description><![CDATA[原文：http://golang.org/doc/code.html
简述
这篇文档描述了如何去写一个新的 package 和怎么去测试。本文假设你已经按照安装文档装好Go。
在修改一个存在的 package 或者新建立一个package，确保先发一封邮件到 mailing list，告诉大家你想做什么。这样有助于不要重复造轮子，在写代码之前最好讨论下。
社区资源
如果想获取实时帮助，可以加入 Freenode 上 IRC 频道 #go-nuts。
Go 语言官方邮件列表是 Go nuts.
Bugs 可以参考 Go issue.
对于那些想尝试开发代码的用户，这里有另外一个邮件列表 golang-checkins，邮件里包含了那些刚提交到 Go 代码库的消息。
建立Go包
下面的源码假设 package 的导入路径是 x/y，约定下保存的路径是：$GOROOT/src/pkg/x/y
Makefile
这将是很好的利用 Go-specific 工具里安排源码结构，如何按照顺序和构建代码。Go 使用 GUN make。所以首先在一个新的package 文件夹里建立一个 Makefile。最简单的做法就是从 src/pkg/container/vector/Makefile 源码包里拷贝一份。
include ../../../Make.$(GOARCH)

TARG=container/vector
GOFILES=\
	intvector.go\
	stringvector.go\
	vector.go\

include ../../../Make.pkg
当然在上面的源码包之外写一个新的 package ，通常的 Makefile 如下：
include $(GOROOT)/src/Make.$(GOARCH)

TARG=mypackage
GOFILES=\
	my1.go\
	my2.go\

include $(GOROOT)/src/Make.pkg
第一行 include 标准的定义和规则，package 的路径一般相对路径来代替 $(GOROOT)/src ，这样做到目的就是防止 make 时候 $(GOROOT) 含有空格，这样做很方便开发中使用Go。
TRAG 是包安装路径，这行就是其他程序导入到名字。在 Go 源码中，这个名字必须和文件夹中的 Makefile 中的一致，不需要 $GOROOT/src/pkg/ 前缀。在源码之外，你可以任意起名而不要和标准 package 的重名即可。常见的做法是独立一个 package 名：myname/tree, myname/filter，确保你的代码在 [...]]]></description>
			<content:encoded><![CDATA[<p>原文：<a href="http://golang.org/doc/code.html" target="_blank">http://golang.org/doc/code.html</a></p>
<p><strong>简述</strong></p>
<p><strong></strong>这篇文档描述了如何去写一个新的 package 和怎么去测试。本文假设你已经按照<a href="http://golang.org/doc/install.html" target="_blank">安装文档</a>装好Go。</p>
<p>在修改一个存在的 package 或者新建立一个package，确保先发一封邮件到 <a href="http://groups.google.com/group/golang-nuts" target="_blank">mailing list</a>，告诉大家你想做什么。这样有助于不要重复造轮子，在写代码之前最好讨论下。</p>
<p><strong>社区资源</strong></p>
<p><strong></strong>如果想获取实时帮助，可以加入 <a href="http://freenode.net/" target="_blank">Freenode</a> 上 IRC 频道 #go-nuts。</p>
<p>Go 语言官方邮件列表是 <a href="http://groups.google.com/group/golang-nuts" target="_blank">Go nuts</a>.</p>
<p>Bugs 可以参考<a href="http://code.google.com/p/go/issues/list" target="_blank"> Go issue</a>.</p>
<p>对于那些想尝试开发代码的用户，这里有另外一个邮件列表 <a href="http://groups.google.com/group/golang-checkins" target="_blank">golang-checkins</a>，邮件里包含了那些刚提交到 Go 代码库的消息。</p>
<p><strong>建立Go包</strong></p>
<p><strong></strong>下面的源码假设 package 的导入路径是 x/y，约定下保存的路径是：$GOROOT/src/pkg/x/y</p>
<p><strong>Makefile</strong></p>
<p>这将是很好的利用 Go-specific 工具里安排源码结构，如何按照顺序和构建代码。Go 使用 GUN make。所以首先在一个新的package 文件夹里建立一个 Makefile。最简单的做法就是从 <a href="http://golang.org/src/pkg/container/vector/Makefile" target="_blank">src/pkg/container/vector/Makefile</a> 源码包里拷贝一份。</p>
<pre>include ../../../Make.$(GOARCH)

TARG=container/vector
GOFILES=\
	intvector.go\
	stringvector.go\
	vector.go\

include ../../../Make.pkg</pre>
<p>当然在上面的源码包之外写一个新的 package ，通常的 Makefile 如下：</p>
<pre>include $(GOROOT)/src/Make.$(GOARCH)

TARG=mypackage
GOFILES=\
	my1.go\
	my2.go\

include $(GOROOT)/src/Make.pkg</pre>
<p>第一行 include 标准的定义和规则，package 的路径一般相对路径来代替 $(GOROOT)/src ，这样做到目的就是防止 make 时候 $(GOROOT) 含有空格，这样做很方便开发中使用Go。</p>
<p>TRAG 是包安装路径，这行就是其他程序导入到名字。在 Go 源码中，这个名字必须和文件夹中的 Makefile 中的一致，不需要 $GOROOT/src/pkg/ 前缀。在源码之外，你可以任意起名而不要和标准 package 的重名即可。常见的做法是独立一个 package 名：myname/tree, myname/filter，确保你的代码在 myname 里，运行 make install，将会编译后把二进制文件放入 $GOROOT/pkg，可以很方便的找到。</p>
<p>GOFILES 放入文件内需要编译的源码列表。多行用 \ 字符隔开。</p>
<p>如果想在 Go 源码树中新建包，需要添加列表到 $GOROOT/src/pkg/Makefile 中作为标准库编译，编译运行：</p>
<pre>cd $GOROOT/src/pkg
./deps.b</pre>
<p>更新依赖文件 Make.deps （这是每次 make all 或者 make build 都需要）</p>
<p><strong>Go 源文件</strong></p>
<p><strong></strong>在每个源码里第一行的名字应该是 Makefile 里面定义的 package 名，这里的 name 是作为默认的名字导入。（包里的每个 package 名都应该是同样的名字）Go的惯例是用路径的最后一个元素作为名字，比如 &#8220;crypto/rot13&#8243; 应该是 rot13。到目前为止，Go 是依靠 package 名字来确定一个二进制的文件，当然可能会很快的取消。</p>
<p>Go 是在一个包内编译源码文件，在一个文件定义常量，变量，类型或者函数，在其他文件内适用不需要再定义和声明。</p>
<p>想写一个干净而优美的 Go 代码不在本文范围。请参考<a href="http://golang.org/doc/effective_go.html" target="_blank">深入 Go 文档</a>吧。</p>
<p><strong>测试</strong></p>
<p><strong></strong>Go 有一个轻量级的测试代码框架：gotest。编写一个测试代码，只需要新建一个跟你源码名字一样，加上：_test.go 即可，测试函数一般是 func TestXXX (t *testing.T)。每次运行测试其中的函数。如果想返回错误的话一般是返回： t.Error 或 t.Fail，测试时候就会抛错。详细 gotest 测试方法请参考：<a href="http://golang.org/cmd/gotest/" target="_blank">http://golang.org/pkg/testing/</a></p>
<p>*_test.go 不需要在 Makefile 中声明。</p>
<p>运行测试，编译时候 make test 即可，和 gotest 效果一样。如果想单独测试某一个源码，比如：one_test.go，则运行：gotest one_test.go。</p>
<p>如果你的修改影响性能，可以添加一个性能测试函数（参考：<a href="http://golang.org/cmd/gotest/" target="_blank">http://golang.org/pkg/testing/</a>），然后运行：gotest -benchmarks=.</p>
<p>当你新的代码已经通过测试，也能运行，你就可以 review 和 commit.  <a href="http://golang.org/doc/contribute.html" target="_blank">http://golang.org/doc/contribute.html</a>。</p>
<p><strong>一个测试的例子</strong></p>
<p>这是一个名字叫 numbers 测试 package ，定义了一个叫 Double 的函数，返回一个整型，结果是输入的参数乘以2。一共有三个文件。</p>
<p>第一个是 numbers.go</p>
<pre>package numbers

func Double(i int) int {
	return i * 2
}</pre>
<p>第二个是测试文件 numbers_test.go</p>
<pre>package numbers

import (
	"testing"
)

type doubleTest struct {
	in, out int
}

var doubleTests = []doubleTest{
	doubleTest{1, 2},
	doubleTest{2, 4},
	doubleTest{-5, -10},
}

func TestDouble(t *testing.T) {
	for _, dt := range doubleTests {
		v := Double(dt.in)
		if v != dt.out {
			t.Errorf("Double(%d) = %d, want %d.", dt.in, v, dt.out)
		}
	}
}</pre>
<p>最后是 Makefile 文件</p>
<pre>include $(GOROOT)/src/Make.$(GOARCH)

TARG=numbers
GOFILES=\
	numbers.go\

include $(GOROOT)/src/Make.</pre>
<p>运行 make install 将会构建和安装包到 GOROOT/pkg/ 文件夹内（他在系统的任何地方导入调用）。</p>
<p>运行 make test （或者 gotest）将会重新构建包，并会运行 numbers_test.go 中的 TestDouble 函数。如果输出 &#8220;PASS&#8221; 则表示测试成功通过。如果不是2到3的倍数，将会看到错误报告。</p>
<p>更详细的请查看<a href="http://golang.org/cmd/gotest/" target="_blank"> gotest 文档</a>和<a href="http://golang.org/pkg/testing/" target="_blank">测试package</a>文档。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/297">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/297#comments">7 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/297&title=如何写 Go 代码？">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/go" rel="tag">Go</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/297/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Pylons 入门实例教程 &#8211; Hello</title>
		<link>http://chenxiaoyu.org/blog/archives/294</link>
		<comments>http://chenxiaoyu.org/blog/archives/294#comments</comments>
		<pubDate>Mon, 28 Jun 2010 12:41:20 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Pylons]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/?p=294</guid>
		<description><![CDATA[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: [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://pylonshq.com/" target="_blank">Pylons</a> 是 Python 的一个轻量级 MVC Web 开发框架，跟另外一个框架 <a href="http://turbogears.org/" target="_blank">TurboGears</a> 比较相似，都是集合了一些优秀的组件而成。比如对 Request URL 采用了 Route，Template 采用了 <a href="http://www.makotemplates.org/" target="_blank">Mako</a>，数据库层则采用了ORM <a href="http://sqlalchemy.org/" target="_blank">SQLAlchemy</a>，当然，这些组件只是默认，你还可以根据自己喜好来选择其他组件，比如你可以采用 Jinja2 或 Genshi 模板，ORM也可以采用 SQLObject。完全是自由组合。</p>
<p>废话少说，现在开始安装吧。</p>
<pre>smallfish@debian:~$ sudo aptitude install python-pylons</pre>
<p>Debian/Ubuntu 系列系统可以直接 aptitude 安装，当然你也可以使用 easy_install 或者源码安装。</p>
<pre>smallfish@debian:~$ sudo easy_install Pylons</pre>
<p>更多安装文档请参考官网安装部分，<a href="http://pylonshq.com/docs/en/1.0/gettingstarted/#installing">http://pylonshq.com/docs/en/1.0/gettingstarted/#installing</a></p>
<p>好了，安装结束，来一个经典的Hello程序吧。</p>
<pre>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</pre>
<p>下面输出略过，大致解说一下。Pylons 程序可以用 Paste 自动生成一些代码，包括controller。还可以运行 HTTP 服务来测试。</p>
<p>-t  表示自动创建的模板，可以如下来查看有哪些选项，更多就参考 help 吧。</p>
<pre>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</pre>
<p>看一下hello的目录结构：</p>
<pre>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</pre>
<p>这里具体各个文件意思就不讲解了，程序主体部分都在hello/hello目录下，development.ini 和 test.ini 分别是服务启动的配置文件，用于测试和开发环境。开始先运行一下，看效果吧。。</p>
<pre>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</pre>
<p>在浏览器中打开：http://127.0.0.1:5000 看到页面了吧？恭喜。</p>
<p>继续，写一个简单的显示 hi的 controller 程序吧。</p>
<pre>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</pre>
<p>自动生成程序和 test 文件。paster 启动服务不需要重启会自动加载，可以浏览器访问：http://127.0.0.1:5000/hi/index</p>
<p>很简单吧，打开 hi.py，基本如下：</p>
<pre>class HiController(BaseController):

    def index(self):
        # Return a rendered template
        #return render('/hi.mako')
        # or, return a response
        return 'Hello World'</pre>
<p>上面注释部分可以 return 一个模板文件，模板放入 templates 目录下即可。</p>
<p>去除上面的 return &#8216;Hello&#8217; 返回 return render(&#8216;/hi.mako&#8217;)</p>
<pre>smallfish@debian:~/workspace/python/hello$ vi hello/templates/hi.mako
% for key, value in request.environ.items():
 ${key} = ${value}
% endfor</pre>
<p>刷新 http://127.0.0.1:5000/hi/index ，可以看到一些环境变量的输出了吧。</p>
<p>今天就简单的说到这里吧，下回来一个完整的例子，包括URL、模板、数据库和Session的实例。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/294">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/294#comments">2 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/294&title=Pylons 入门实例教程 &#8211; Hello">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/pylons" rel="tag">Pylons</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/294/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PostgreSQL COPY 导入/导出数据</title>
		<link>http://chenxiaoyu.org/blog/archives/288</link>
		<comments>http://chenxiaoyu.org/blog/archives/288#comments</comments>
		<pubDate>Wed, 02 Jun 2010 12:30:20 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/?p=288</guid>
		<description><![CDATA[COPY 命令可以快速的导入数据到 PostgreSQL 中，文件格式类似CVS之类。适合批量导入数据，比 \i 和恢复数据表快。
导出表数据到文件或 STDOUT ：
COPY tablename [(column [, ...])]
   TO {'filename' &#124; STDOUT}
   [[WITH]
      [BINARY]
      [OIDS]
      [DELIMITER [AS] 'delimiter']
      [NULL [AS] 'null string']
      [...]]]></description>
			<content:encoded><![CDATA[<p>COPY 命令可以快速的导入数据到 PostgreSQL 中，文件格式类似CVS之类。适合批量导入数据，比 \i 和恢复数据表快。</p>
<p>导出表数据到文件或 STDOUT ：</p>
<pre>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 [, ...]]</pre>
<p>导入文件或者 STDIN 到表中：</p>
<pre>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 [, ...]]</pre>
<p>导出表 employee 到默认输出 STDOUT：</p>
<pre>psql&gt; COPY employee TO STDOUT;
1       JG100011        Jason Gilmore         jason@example.com
2       RT435234        Robert Treat          rob@example.com
3       GS998909        Greg Sabino Mullane   greg@example.com
4       MW777983        Matt Wade             matt@example.com</pre>
<p>导出表 employee 到 sql 文件：</p>
<pre>psql&gt; COPY employee TO '/home/smallfish/employee.sql';</pre>
<p>从文件导入数据：</p>
<pre>psql&gt; COPY employeenew FROM '/home/smallfish/employee.sql';
psql&gt; SELECT * FROM employeenew;
employeeid  | employeecode |     name            |       email
------------+--------------+---------------------+---------------
          1 | JG100011     | Jason Gilmore       | jason@example.com
          2 | RT435234     | Robert Treat        | rob@example.com
          3 | GS998909     | Greg Sabino Mullane | greg@example.com
          4 | MW777983     | Matt Wade           | matt@example.com
(4 rows)</pre>
<p>输出对象ID（OIDS）：</p>
<pre>psql&gt; COPY employee TO STDOUT OIDS;
24627  1       GM100011        Jason Gilmore         jason@example.com
24628  2       RT435234        Robert Treat          rob@example.com
24629  3       GS998909        Greg Sabino Mullane   greg@example.com
24630  4       MW777983        Matt Wade             matt@example.com</pre>
<p>指定导出间隔符，默认是 \t ，这里为 | ：</p>
<pre>psql&gt;COPY employee TO STDOUT DELIMITER '|';
1|GM100011|Jason Gilmore|jason@example.com
2|RT435234|Robert Treat|rob@example.com
3|GS998909|Greg Sabino Mullane|greg@example.com
4|MW777983|Matt Wade|matt@example.com</pre>
<p>导入文件数据，指定间隔符为 | ：</p>
<pre>psql&gt; COPY employeenew FROM '/home/smallfish/employee.sql' DELIMITER |;</pre>
<p>导出指定字段的数据：</p>
<pre>psql&gt; COPY employee (name,email) TO STDOUT;
Jason Gilmore         jason@example.com
Robert Treat          rob@example.com
Greg Sabino Mullane   greg@example.com
Matt Wade             matt@example.com</pre>
<p>为 NULL 字段设置默认值：</p>
<pre>psql&gt; COPY employee TO STDOUT NULL 'no email';
Jason Gilmore         no email
Robert Treat          rob@example.com
Greg Sabino Mullane   greg@example.com
Matt Wade             no email</pre>
<p>导出为CVS格式：</p>
<pre>psql&gt; COPY employee (name, email) TO '/home/smallfish/employee.csv' CSV HEADER;</pre>
<p>参考资料：<a href="http://apress.com/book/view/9781590595473" target="_blank">Apress Beginning PHP and PostgreSQL 8: From Novice to Professional </a></p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/288">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/288#comments">9 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/288&title=PostgreSQL COPY 导入/导出数据">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/postgresql" rel="tag">PostgreSQL</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/288/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Go 语言模块安装工具：goinstall</title>
		<link>http://chenxiaoyu.org/blog/archives/279</link>
		<comments>http://chenxiaoyu.org/blog/archives/279#comments</comments>
		<pubDate>Sun, 30 May 2010 13:27:00 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Go]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/?p=279</guid>
		<description><![CDATA[
文档地址：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。

© smallfish for smallfish [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://golang.org/doc/logo-153x55.png" alt="" /></p>
<p>文档地址：<a href="http://golang.org/cmd/goinstall/" target="_blank">http://golang.org/cmd/goinstall/</a> Go模块列表：<a href="http://godashboard.appspot.com/package" target="_blank">http://godashboard.appspot.com/package</a></p>
<p>goinstall 主要是方便安装第三方模块，目前支持 hg(mercurial)，git，svn三种版本控制系统。</p>
<p>下面来举例怎么安装 web.go 模块。源地址是：<a href="http://github.com/hoisie/web.go" target="_blank">http://github.com/hoisie/web.go</a></p>
<pre>smallfish@debian:~$ goinstall -dashboard=true github.com/hoisie/web.go</pre>
<p>根据网速快慢，过一段时间会结束。期间木有任何提示。（可以加上 -v=true 参数，可以显示安装过程和提示。）</p>
<p>查看下安装的目录和路径：</p>
<pre>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</pre>
<p>代码示例：</p>
<pre>import (web "github.com/hoisie/web.go")</pre>
<p>另外注意点，官方文档里 -update 选项现在版本里已经缩写，改成 -u。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/279">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/279#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/279&title=Go 语言模块安装工具：goinstall">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/go" rel="tag">Go</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/279/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cython 教程 &#8211; 调用外部C语言函数</title>
		<link>http://chenxiaoyu.org/blog/archives/275</link>
		<comments>http://chenxiaoyu.org/blog/archives/275#comments</comments>
		<pubDate>Sun, 30 May 2010 11:11:01 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Cython]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/?p=275</guid>
		<description><![CDATA[一般情况完全可以在 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",
 [...]]]></description>
			<content:encoded><![CDATA[<p>一般情况完全可以在 Python 里导入 from math import sin 然后调用 sin() 函数。然而，调用C里面的 sin() 函数速度会更快，尤其在复杂的循环里。在 Cython 里可以这样声明和使用：</p>
<pre>cdef extern from "math.h":
    double sin(double)

cdef double f(double x):
    return sin(x*x)</pre>
<p>请注意，上面的代码声明了 math.h 里的函数，提供给 Cython 使用。C编译器在编译时将会看到 math.h 的声明，但 Cython 不会去分析 math.h 和单独的定义。</p>
<p>当调用一个C函数时，一定要注意引入适当的链接库。这个依赖于特定的平台；下面的例子可以在Linux和Mac OS X下运行：</p>
<pre>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
)</pre>
<p>跟从 math 库里使用 sin() 函数一样，它可以声明和导入任何C库，Cython会生成正确的共享或者静态链接库。</p>
<p>参考：<a href="http://docs.cython.org/src/tutorial/external.html">http://docs.cython.org/src/tutorial/external.html</a></p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/275">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/275#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/275&title=Cython 教程 &#8211; 调用外部C语言函数">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/cython" rel="tag">Cython</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/275/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>其实我就是个演员</title>
		<link>http://chenxiaoyu.org/blog/archives/269</link>
		<comments>http://chenxiaoyu.org/blog/archives/269#comments</comments>
		<pubDate>Fri, 21 May 2010 14:05:33 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/?p=269</guid>
		<description><![CDATA[注：此文系纯水贴，正经人士请绕道。 :)
场景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）都略懂的角色。
不同的时间，演绎不同的角色。过去是，现在是，将来也是。

© smallfish for smallfish logs, 2010. &#124;
Permalink &#124;
18 comments &#124;
Add to
del.icio.us

Post tags: 







Feed enhanced by Better Feed from  Ozh
]]></description>
			<content:encoded><![CDATA[<p>注：此文系纯水贴，正经人士请绕道。 :)</p>
<p>场景1<br />
某日很HI的写着程序，凑巧做网页的美工不在，活又耽误不得，只能捋起袖子，装起了Dreamweaver+Fireworks，三下五除二搞定了前端页面。话说自从开始写程序起，就很少碰这些高级玩意了。现在只是偶尔PS修修抠抠图，享受下钢笔抠图小YY一把就足够了。<br />
其实在做程序之前，俺一直是个美工，作图做页面只不过信手拈来。</p>
<p>场景2<br />
简历给某朋友看了之后，很惊讶道：原来你是做Java的？只好含泪不语+内流满面了。难道我博客只写Python或者Perl，不意味着俺就是折腾这些的哇。只好幽幽的坦然回答之：其实我的主业是Java开发者，做了六年多。<br />
其实动态语言只是我的业余爱好，顺带写了点分享的博文而已。只不过对外闭口没提Java。</p>
<p>场景3<br />
有些朋友看我经常推荐PostgreSQL，就问俺：Pg和MySQL到底有哪些区别？描述种种，感觉可能他也云里雾里。遂让他自己说说需求，最后还是推荐他用MySQL。顺带讲述了一些常用优化和监控的办法。丫又惊讶的说原来你一直用的MySQL啊。好吧，只好再次内流。<br />
其实我正儿八经用数据库最长久的就是MySQL了，基本也有六年多了把。Pg只是我的业余爱好，没事研究了下，寻找下乐趣而已。</p>
<p>如此场景会继续重现，遂略过数字。。。</p>
<p>其实，我就是个演员。对系统（Linux）、语言（Java/Python/Perl）、数据库（MySQL/PostgreSQL）都略懂的角色。</p>
<p>不同的时间，演绎不同的角色。过去是，现在是，将来也是。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/269">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/269#comments">18 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/269&title=其实我就是个演员">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/269/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>[图文解说] Virtual Box 通过 NAT(默认) 共享虚拟机中的服务</title>
		<link>http://chenxiaoyu.org/blog/archives/247</link>
		<comments>http://chenxiaoyu.org/blog/archives/247#comments</comments>
		<pubDate>Mon, 10 May 2010 13:13:11 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[VirtualBox]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=247</guid>
		<description><![CDATA[Virtual Box 是个不错的虚拟机，小巧，功能也齐全。好像有点推销鸟。说正题，上次有个朋友就提到怎么能主机里访问虚拟机里的服务，昨晚实验了下，颇为顺利。记录下。这里利用的是默认的NAT上网，也就是共享主机上网，而不是设置独立的IP。
主机：Win XP
虚拟：Ubuntu 9.10
目的：Win里ssh进Ubuntu，能访问里面提供的服务。
主要是通过 VBoxManage setextradata 设置一些属性。
先上几个步骤图把。注意一下修改，先得关闭虚拟机，修改完事以后再启动。
1. 查看虚拟机中的名称：ubuntu9

2. 进入本机Vbox目录，运行VBoxManage，查看下。


 3. 添加三个项目
下面的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

4. 再次查看

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"

© smallfish for smallfish logs, 2010. &#124;
Permalink &#124;
5 comments &#124;
Add [...]]]></description>
			<content:encoded><![CDATA[<p>Virtual Box 是个不错的虚拟机，小巧，功能也齐全。好像有点推销鸟。说正题，上次有个朋友就提到怎么能主机里访问虚拟机里的服务，昨晚实验了下，颇为顺利。记录下。这里利用的是默认的NAT上网，也就是共享主机上网，而不是设置独立的IP。</p>
<p>主机：Win XP<br />
虚拟：Ubuntu 9.10</p>
<p>目的：Win里ssh进Ubuntu，能访问里面提供的服务。</p>
<p>主要是通过 VBoxManage setextradata 设置一些属性。</p>
<p>先上几个步骤图把。注意一下修改，先得关闭虚拟机，修改完事以后再启动。</p>
<p><strong>1. 查看虚拟机中的名称：ubuntu9</strong></p>
<p><img title="vbox-nat-0" src="http://chenxiaoyu.org/wp-content/uploads/2010/05/vbox-nat-0.gif" alt="" /></p>
<p><strong>2. 进入本机Vbox目录，运行VBoxManage，查看下。</strong></p>
<p><img class="alignnone size-full wp-image-249" title="vbox-nat-1" src="http://chenxiaoyu.org/wp-content/uploads/2010/05/vbox-nat-1.gif" alt="" width="669" height="315" /></p>
<p><a href="http://chenxiaoyu.org/wp-content/uploads/2010/05/vbox-nat-5.gif"></a><br />
<strong> 3. 添加三个项目</strong></p>
<p>下面的pcnet是vbox里的网络设置，0是表示第一个网卡，后面一次类推。22是ssh端口，映射到主机的22端口。</p>
<pre>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</pre>
<p><img title="vbox-nat-2" src="http://chenxiaoyu.org/wp-content/uploads/2010/05/vbox-nat-2.gif" alt="" width="660" height="391" /></p>
<p><a href="http://chenxiaoyu.org/wp-content/uploads/2010/05/vbox-nat-2.gif"></a><strong>4. 再次查看</strong></p>
<p><img class="alignnone size-full wp-image-251" title="vbox-nat-3" src="http://chenxiaoyu.org/wp-content/uploads/2010/05/vbox-nat-3.gif" alt="" width="662" height="348" /></p>
<p><strong>5. 启动虚拟机。</strong></p>
<p><strong>6. 设置putty登陆之。</strong></p>
<p><img class="alignnone size-full wp-image-252" title="vbox-nat-4" src="http://chenxiaoyu.org/wp-content/uploads/2010/05/vbox-nat-4.gif" alt="" width="454" height="272" /></p>
<p><img class="alignnone size-full wp-image-253" title="vbox-nat-5" src="http://chenxiaoyu.org/wp-content/uploads/2010/05/vbox-nat-5.gif" alt="" width="569" height="175" /></p>
<p>到这里已经顺利ssh 到127.0.0.1，如果想访问虚拟机里的web服务器呢？同样很简单。</p>
<p>只要如下设置，web端口为81，跟上面也雷同：</p>
<pre>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</pre>
<p>另外如果想清空上面设置的选项，只要不设置后面的值即可：</p>
<pre>VBoxManage setextradata "ubuntu9" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/web/Protocol"</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/247">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/247#comments">5 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/247&title=[图文解说] Virtual Box 通过 NAT(默认) 共享虚拟机中的服务">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/virtualbox" rel="tag">VirtualBox</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/247/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>[译] MongoDB 入门教程</title>
		<link>http://chenxiaoyu.org/blog/archives/242</link>
		<comments>http://chenxiaoyu.org/blog/archives/242#comments</comments>
		<pubDate>Tue, 27 Apr 2010 12:39:05 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[MongoDB]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=242</guid>
		<description><![CDATA[原文参见：http://www.mongodb.org/display/DOCS/Tutorial
启动数据库
下载 MongoDB, 解压后并启动:
$ bin/mongod
MongoDB 默认存储数据目录为 /data/db/ (或者 c:\data\db), 当然你也可以修改成不同目录, 只需要指定 &#8211;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
&#62;
&#8220;connecting to:&#8221; 这个会显示你正在使用的数据库的名称. 想换数据库的话可以:
&#62; use mydb
可以输入 help 来查看所有的命令.
插入数据到集合
下面我们来建立一个test的集合并写入一些数据. 建立两个对象, j 和 t , 并保存到集合中去.
在例子里  &#8216;&#62;&#8217;  来表示是 shell 输入提示符
&#62; j [...]]]></description>
			<content:encoded><![CDATA[<p>原文参见：<a href="http://www.mongodb.org/display/DOCS/Tutorial" target="_blank">http://www.mongodb.org/display/DOCS/Tutorial</a></p>
<p><strong>启动数据库</strong></p>
<p>下载 <a href="http://www.mongodb.org/display/DOCS/Downloads" target="_blank">MongoDB</a>, 解压后并启动:</p>
<pre>$ bin/mongod</pre>
<p>MongoDB 默认存储数据目录为 /data/db/ (或者 c:\data\db), 当然你也可以修改成不同目录, 只需要指定 &#8211;dbpath 参数:</p>
<pre>$ bin/mongod --dbpath /path/to/my/data/dir</pre>
<p><strong>获取数据库连接</strong></p>
<p>现在我们就可以使用自带的shell工具来操作数据库了. (我们也可以使用各种编程语言的驱动来使用MongoDB, 自带的shell工具可以方便我们管理数据库)</p>
<p>启动 MongoDB JavaScript 工具:</p>
<pre>$ bin/mongo</pre>
<p>默认 shell 连接的是本机localhost 上面的 test库, 会看到:</p>
<pre>MongoDB shell version: 0.9.8
url: test
connecting to: test
type "help" for help
&gt;</pre>
<p>&#8220;connecting to:&#8221; 这个会显示你正在使用的数据库的名称. 想换数据库的话可以:</p>
<pre>&gt; use mydb</pre>
<p>可以输入 help 来查看所有的命令.</p>
<p><strong>插入数据到集合</strong></p>
<p>下面我们来建立一个test的集合并写入一些数据. 建立两个对象, j 和 t , 并保存到集合中去.<br />
在例子里  &#8216;&gt;&#8217;  来表示是 shell 输入提示符</p>
<pre>&gt; j = { name : "mongo" };
{"name" : "mongo"}
&gt; t = { x : 3 };
{ "x" : 3  }
&gt; db.things.save(j);
&gt; db.things.save(t);
&gt; db.things.find();
{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}
{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}
&gt;</pre>
<p>有几点需要注意下 :</p>
<ul>
<li>不需要预先建立一个集合. 在第一次插入数据时候会自动建立.</li>
<li>在例子其实可以存储任何结构的数据, 当然在实际应用我们存储的还是相同元素的集合. 这个特性其实可以在应用里很灵活, 你不需要类似 alter table 来修改你的数据结构</li>
<li>每次插入数据时候对象都会有一个ID, 名字叫 _id.</li>
</ul>
<p>当你运行不同的例子, 你的对象ID值都是不同的.</p>
<p>下面再加点数据:</p>
<pre>&gt; for( var i = 1; i &lt; 10; i++ ) db.things.save( { x:4, j:i } ); &gt; 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")}</pre>
<p>请注意下, 这里循环次数是10, 但是只显示到8, 还有2条数据没有显示.</p>
<p>如果想继续查询下面的数据只需要使用 it 命令, 就会继续下面的数据:</p>
<pre>{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}
{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}</pre>
<p>继续</p>
<pre>&gt; it
{"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")}
{"x" : 4 , "j" : 10 , "_id" : ObjectId("497cf87151712cf7758fbdc6")}</pre>
<p>从技术上讲 find() 返回一个游标对象. 但在上面的例子里, 并没有拿到一个游标的变量. 所以 shell 自动遍历游标, 返回一个初始化的set, 并允许我们继续用 it 迭代输出.</p>
<p>当然我们也可以直接用游标来输出, 不过这个是下一部分的内容了.</p>
<p><strong>查询数据</strong></p>
<p>在没有深入查询之前, 我们先看看怎么从一个查询中返回一个游标对象. 可以简单的通过 find() 来查询, 他返回一个任意结构的集合. 如果实现特定的查询稍后讲解.</p>
<p>实现上面同样的查询, 然后通过 while 来输出:</p>
<pre>&gt; var cursor = db.things.find();
&gt; 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")}
&gt;</pre>
<p>上面的例子显示了游标风格的迭代输出. hasNext() 函数告诉我们是否还有数据, 如果有则可以调用 next() 函数. 这里我们也用了自带的 tojson() 方法返回一个标准的 JSON 格式数据.</p>
<p>当我们使用的是 JavaScript shell, 可以用到JS的特性, forEach 就可以输出游标了. 下面的例子就是使用 forEach() 来循环输出:</p>
<pre>&gt; 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")}
&gt;</pre>
<p>forEach() 必须定义一个函数供每个游标元素调用.</p>
<p>在 mongo shell 里, 我们也可以把游标当作数组来用 :</p>
<pre>&gt; var cursor = db.things.find();
&gt; print (tojson(cursor[4]));
{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}</pre>
<p>使用游标时候请注意占用内存的问题, 特别是很大的游标对象, 有可能会内存溢出. 所以应该用迭代的方式来输出.</p>
<p>下面的示例则是把游标转换成真实的数组类型:</p>
<pre>&gt; var arr = db.things.find().toArray();
&gt; arr[5];
{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}</pre>
<p>请注意这些特性只是在 mongo shell 里使用, 而不是所有的其他应用程序驱动都支持.</p>
<p>MongoDB 游标对象不是没有快照 &#8211; 如果有其他用户在集合里第一次或者最后一次调用 next(), 你可以得不到游标里的数据. 所以要明确的锁定你要查询的游标.</p>
<p><strong>指定条件的查询</strong></p>
<p>到这里我们已经知道怎么从游标里实现一个查询并返回数据对象, 下面就来看看怎么根据指定的条件来查询.</p>
<p>下面的示例就是说明如何执行一个类似SQL的查询, 并演示了怎么在 MongoDB 里实现. 这是在 MongoDB shell 里查询, 当然你也可以用其他的应用驱动或者语言来实现:</p>
<pre>SELECT * FROM things WHERE name="mongo"</pre>
<pre>&gt; db.things.find({name:"mongo"}).forEach(function(x) { print(tojson(x));});
{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}
&gt;</pre>
<pre>SELECT * FROM things WHERE x=4</pre>
<pre>&gt; 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")}
&gt;</pre>
<p>查询条件是 { a:A, b:B, &#8230; } 类似 &#8220;where a==A and b==B and &#8230;&#8221;, 更多的查询方式可以参考 Mongo 开发教程部分.</p>
<p>上面显示的是所有的元素, 当然我们也可以返回特定的元素, 类似于返回表里某字段的值, 只需要在 find({x:4}) 里指定元素的名字, 比如 j:</p>
<pre>SELECT j FROM things WHERE x=4</pre>
<pre>&gt; 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")}
&gt;</pre>
<p>请注意 &#8220;_id&#8221; 元素会一直被返回.</p>
<p><strong>findOne() &#8211; 语法糖</strong></p>
<p>为了方便, mongo shell (其他驱动) 避免游标的可能带来的开销, 提供一个findOne() 函数. 这个函数和 find() 参数一样, 不过他返回游标里第一条数据, 或者返回 null 空数据库.</p>
<p>作为一个例子, name==&#8217;mongo&#8217; 可以用很多方法来实现, 可以用 next() 来循环游标(需要校验是否为null), 或者当做数组返回第一个元素.</p>
<p>但是用 findOne() 方法则更简单和高效:</p>
<pre>&gt; var mongo = db.things.findOne({name:"mongo"});
&gt; print(tojson(mongo));
{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}
&gt;</pre>
<p>findOne 方法更跟 find({name:&#8221;mongo&#8221;}).limit(1) 一样.</p>
<p><strong>limit() 查询</strong></p>
<p>你可以需要限制结果集的长度, 可以调用 limit 方法.</p>
<p>这是强烈推荐高性能的原因, 通过限制条数来减少网络传输, 例如:</p>
<pre>&gt; db.things.find().limit(3);
in cursor for : DBQuery: example.things -&gt;
{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}
{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}
{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}
&gt;</pre>
<p><strong>更多帮助</strong></p>
<p>除非了一般的 help 之外, 你还可以查询 help 数据库和db.whatever 来查询具体的说明.</p>
<p>如果你对一个函数要做什么, 你可以不输入 {{()}} 这些结束的括号则可以输出实现的源码, 例如:</p>
<pre>&gt; 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);
}</pre>
<p>mongo 是一个完整的 JavaScript shell程序, 所以在 shell 里完全可以私用JS的方法、类、语法. 此外, MongoDB 定义很多自己的类和全局变量 (比如 db). 这里可以查看完整的API说明 <a href="http://api.mongodb.org/js/" target="_blank">http://api.mongodb.org/js/</a>.</p>
<p><strong>接下来</strong></p>
<p>看完这篇教程后下一步则看MongoDB更详细的文档 <a href="http://www.mongodb.org/display/DOCS/Manual" target="_blank">http://www.mongodb.org/display/DOCS/Manual</a></p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/242">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/242#comments">8 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/242&title=[译] MongoDB 入门教程">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/mongodb" rel="tag">MongoDB</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/242/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Python ConfigParser 与 ConfigObj INI 配置读写顺序</title>
		<link>http://chenxiaoyu.org/blog/archives/239</link>
		<comments>http://chenxiaoyu.org/blog/archives/239#comments</comments>
		<pubDate>Mon, 19 Apr 2010 12:27:25 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=239</guid>
		<description><![CDATA[默认的ConfigParser对于选项是按照字母顺序排列的。如下代码：
&#62;&#62;&#62; from ConfigParser import ConfigParser
&#62;&#62;&#62; cf = ConfigParser()
&#62;&#62;&#62; cf.add_section('d')
&#62;&#62;&#62; cf.set('d', 'name', 'smallfish')
&#62;&#62;&#62; cf.add_section('a')
&#62;&#62;&#62; cf.set('a', 'name', 'smallfish2')
&#62;&#62;&#62; cf.write(open('d:/a.ini', 'w'))
&#62;&#62;&#62; cf = None
生成配置如下：
[a]
name = smallfish2
[d]
name = smallfish
翻阅了官方文档似乎对ConfigParser中section的顺序没啥解说，毕竟字典本身就是无序的，如果想修改估计只能从源码入手把。不过有一个ConfigObj库还不错，可以实现顺序，当然功能不仅仅如此啦。下载地址：http://www.voidspace.org.uk/python/configobj.html
代码片段如下：
&#62;&#62;&#62; from configobj import ConfigObj
&#62;&#62;&#62; config = ConfigObj()
&#62;&#62;&#62; config.filename = 'd:/a.ini'
&#62;&#62;&#62; config['d'] = {}
&#62;&#62;&#62; config['d']['name'] = 'smallfish'
&#62;&#62;&#62; config['a'] = {}
&#62;&#62;&#62; config['a']['name'] = 'smallfish2'
&#62;&#62;&#62; config.write()
生成配置如下：
[d]
name = smallfish
[a]
name = smallfish2

© smallfish for smallfish [...]]]></description>
			<content:encoded><![CDATA[<p>默认的ConfigParser对于选项是按照字母顺序排列的。如下代码：</p>
<pre>&gt;&gt;&gt; from ConfigParser import ConfigParser
&gt;&gt;&gt; cf = ConfigParser()
&gt;&gt;&gt; cf.add_section('d')
&gt;&gt;&gt; cf.set('d', 'name', 'smallfish')
&gt;&gt;&gt; cf.add_section('a')
&gt;&gt;&gt; cf.set('a', 'name', 'smallfish2')
&gt;&gt;&gt; cf.write(open('d:/a.ini', 'w'))
&gt;&gt;&gt; cf = None</pre>
<p>生成配置如下：</p>
<pre>[a]
name = smallfish2
[d]
name = smallfish</pre>
<p>翻阅了官方文档似乎对ConfigParser中section的顺序没啥解说，毕竟字典本身就是无序的，如果想修改估计只能从源码入手把。不过有一个ConfigObj库还不错，可以实现顺序，当然功能不仅仅如此啦。下载地址：<a href="http://www.voidspace.org.uk/python/configobj.html" target="_blank">http://www.voidspace.org.uk/python/configobj.html</a></p>
<p>代码片段如下：</p>
<pre>&gt;&gt;&gt; from configobj import ConfigObj
&gt;&gt;&gt; config = ConfigObj()
&gt;&gt;&gt; config.filename = 'd:/a.ini'
&gt;&gt;&gt; config['d'] = {}
&gt;&gt;&gt; config['d']['name'] = 'smallfish'
&gt;&gt;&gt; config['a'] = {}
&gt;&gt;&gt; config['a']['name'] = 'smallfish2'
&gt;&gt;&gt; config.write()</pre>
<p>生成配置如下：</p>
<pre>[d]
name = smallfish
[a]
name = smallfish2</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/239">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/239#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/239&title=Python ConfigParser 与 ConfigObj INI 配置读写顺序">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/239/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>梦想与坚持</title>
		<link>http://chenxiaoyu.org/blog/archives/235</link>
		<comments>http://chenxiaoyu.org/blog/archives/235#comments</comments>
		<pubDate>Thu, 08 Apr 2010 16:15:32 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=235</guid>
		<description><![CDATA[经过几天的适应总算在杭州安定下来了，回归到简单而快乐的上班生活轨道上。
夜深人静的时侯才能静下心来写点关于自己的话题，不再浮躁。
回想这毕业后的六年多的时间，自己都在做些什么？工作的内容在不停的变化，唯一不变的就是坚持了自己的梦想，一个小小的技术梦想。梦想只是目标，而坚持应该是梦想的过程。结果不一定很绚烂，但过程一定要精彩。
第一份工作真的很稚嫩，从文科啥也不懂，菜鸟起步，做起了Web设计和简单的程序编写。当然起步都是需要点时间和积累的。现在还记得为自己做出一个个简单的动画效果而激动无比的场景。随着时间的推移，发觉自己在创意方面的缺乏，两年之后就离开了生活的那个城市。
第二份工作时间很长，四年半的时间。算是一个正规军把 :) 只不过后来也变得有点山寨。收获最大的就是伴随着公司的发展对技术的不断提高要求，接触的很越来越多。最初那种土鳖式的代码工已经不符合了。逐步了解了分层模式，框架，服务器，数据库等等很多有趣的东西。而不仅仅的是把代码写完就完事了。技术上面的提高，当然也带来视野上的扩展。从开始的单一语言发展到后来的多语言结合，单一的数据库到几十台的主从结构，数据应用的分离，数据的切分，缓存系统的应用，以及服务器模块的开发。现在还记得某年的夏天没有空调一帮人赤膊写代码的场景，多hi阿。回想起过去的种种，内心真的难以平静。有时侯想想真的不是想离开，有点无奈。
最近踏上了新的起点，六年以后的第三份工作：淘宝。最初喜欢上淘宝是因为看到的网上办公环境照片，通过一些朋友的了解，里面的武侠文化很吸引自己，想想自己曾经也疯狂迷恋过武侠小说，导致正经的文学没学几篇，很是遗憾阿。经过这几天的初步接触，每天都会有着不同的收获。虽然从事的工作跟过去的内容和岗位都不太一样，但是正因为如此才有更多的好奇与向往。
一直相信只要有坚持，就会有梦想。而不是倒过来，本子电也不多了，洗洗睡吧。祝自己好运，good night！

© smallfish for smallfish logs, 2010. &#124;
Permalink &#124;
8 comments &#124;
Add to
del.icio.us

Post tags: 







Feed enhanced by Better Feed from  Ozh
]]></description>
			<content:encoded><![CDATA[<p>经过几天的适应总算在杭州安定下来了，回归到简单而快乐的上班生活轨道上。</p>
<p>夜深人静的时侯才能静下心来写点关于自己的话题，不再浮躁。</p>
<p>回想这毕业后的六年多的时间，自己都在做些什么？工作的内容在不停的变化，唯一不变的就是坚持了自己的梦想，一个小小的技术梦想。梦想只是目标，而坚持应该是梦想的过程。结果不一定很绚烂，但过程一定要精彩。</p>
<p>第一份工作真的很稚嫩，从文科啥也不懂，菜鸟起步，做起了Web设计和简单的程序编写。当然起步都是需要点时间和积累的。现在还记得为自己做出一个个简单的动画效果而激动无比的场景。随着时间的推移，发觉自己在创意方面的缺乏，两年之后就离开了生活的那个城市。</p>
<p>第二份工作时间很长，四年半的时间。算是一个正规军把 :) 只不过后来也变得有点山寨。收获最大的就是伴随着公司的发展对技术的不断提高要求，接触的很越来越多。最初那种土鳖式的代码工已经不符合了。逐步了解了分层模式，框架，服务器，数据库等等很多有趣的东西。而不仅仅的是把代码写完就完事了。技术上面的提高，当然也带来视野上的扩展。从开始的单一语言发展到后来的多语言结合，单一的数据库到几十台的主从结构，数据应用的分离，数据的切分，缓存系统的应用，以及服务器模块的开发。现在还记得某年的夏天没有空调一帮人赤膊写代码的场景，多hi阿。回想起过去的种种，内心真的难以平静。有时侯想想真的不是想离开，有点无奈。</p>
<p>最近踏上了新的起点，六年以后的第三份工作：淘宝。最初喜欢上淘宝是因为看到的网上办公环境照片，通过一些朋友的了解，里面的武侠文化很吸引自己，想想自己曾经也疯狂迷恋过武侠小说，导致正经的文学没学几篇，很是遗憾阿。经过这几天的初步接触，每天都会有着不同的收获。虽然从事的工作跟过去的内容和岗位都不太一样，但是正因为如此才有更多的好奇与向往。</p>
<p>一直相信只要有坚持，就会有梦想。而不是倒过来，本子电也不多了，洗洗睡吧。祝自己好运，good night！</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/235">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/235#comments">8 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/235&title=梦想与坚持">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/235/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Nginx 启动/重启脚本笔记</title>
		<link>http://chenxiaoyu.org/blog/archives/232</link>
		<comments>http://chenxiaoyu.org/blog/archives/232#comments</comments>
		<pubDate>Sat, 27 Mar 2010 06:28:10 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Nginx]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=232</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Nginx本身可以通过</p>
<pre>kill -HUP `cat /usr/local/nginx/logs/nginx.pid`
</pre>
<p>进行平滑重启的，可以通过ps进程查看一下。效果还是挺不错的。</p>
<p>这里介绍的是另外一种方式service，适合RHEL/CentOS系列。</p>
<p>1. kill nginx进程</p>
<pre>kill `cat /usr/local/nginx/logs/nginx.pid`
</pre>
<p>2. 建立 /etc/init.d/nginx 文件</p>
<pre>#!/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" ] &amp;&amp; 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 ] &amp;&amp; touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] &amp;&amp; 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 &gt;/dev/null 2&gt;&amp;1
}

case "$1" in
    start)
        rh_status_q &amp;&amp; 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</pre>
<p>3. 设置脚本为可执行</p>
<pre>chmod +x /etc/init.d/nginx
</pre>
<p>4.</p>
<pre>/sbin/chkconfig nginx on
</pre>
<p>5. 检查下</p>
<pre>/sbin/chkconfig --list nginx
nginx           0:off   1:off   2:on    3:on    4:on    5:on    6:off
</pre>
<p>完成咯~可以尝试下面方式启动或者重启</p>
<pre>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
</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/232">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/232#comments">2 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/232&title=Nginx 启动/重启脚本笔记">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/nginx" rel="tag">Nginx</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/232/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>web.py 数据库操作指南</title>
		<link>http://chenxiaoyu.org/blog/archives/226</link>
		<comments>http://chenxiaoyu.org/blog/archives/226#comments</comments>
		<pubDate>Fri, 19 Mar 2010 03:30:39 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[web.py]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=226</guid>
		<description><![CDATA[官网地址：http://webpy.org/
web.py是一个小巧灵活的框架，最新稳定版是0.33。这里不介绍web开发部分，介绍下关于数据库的相关操作。
很多Pyer一开始都喜欢自己封装数据库操作类，本人亦如此。不过后来通过观摩web.py的源码，发现其数据库操作部分相当紧凑实用。推荐懒人可以尝试一下。
废话不多，先来安装，有两种方式：
1. easy_install方式，如果木有此工具，可以参考：http://chenxiaoyu.org/blog/archives/23
easy_install web.py
2. 下载源码编译。地址： http://webpy.org/static/web.py-0.33.tar.gz ，解压后执行：
python setup.py install
web.py安装算到此结束，如果想使用其中的db功能，还得借助与相应数据库操作模块，比如MySQLdb、psycopg2。如果需要尝试连接池(database pool)功能，还得装下DBUtils。这几个模块都可以通过easy_install来安装。
下面开始使用吧！
1. 导入模块，定义数据库连接db。
import web
db = web.database(dbn='postgres', db='mydata', user='dbuser', pw='')
2. select 查询
# 查询表
entries = db.select('mytable')

# where 条件
myvar = dict(name="Bob")
results = db.select('mytable', myvar, where="name = $name")
results = db.select('mytable', where="id&#62;100")

# 查询具体列
results = db.select('mytable', what="id,name")

# order by
results = db.select('mytable', order="post_date DESC")

# group
results = db.select('mytable', group="color")

# limit
results = db.select('mytable', limit=10)

# offset
results = db.select('mytable', offset=10)
3. [...]]]></description>
			<content:encoded><![CDATA[<p>官网地址：<a href="http://webpy.org/">http://webpy.org/</a></p>
<p>web.py是一个小巧灵活的框架，最新稳定版是0.33。这里不介绍web开发部分，介绍下关于数据库的相关操作。</p>
<p>很多Pyer一开始都喜欢自己封装数据库操作类，本人亦如此。不过后来通过观摩web.py的源码，发现其数据库操作部分相当紧凑实用。推荐懒人可以尝试一下。</p>
<p>废话不多，先来安装，有两种方式：</p>
<p><strong>1. easy_install方式</strong>，如果木有此工具，可以参考：<a href="http://chenxiaoyu.org/blog/archives/23">http://chenxiaoyu.org/blog/archives/23</a></p>
<pre>easy_install web.py</pre>
<p><strong>2. 下载源码编译</strong>。地址： <a href="http://webpy.org/static/web.py-0.33.tar.gz">http://webpy.org/static/web.py-0.33.tar.gz</a> ，解压后执行：</p>
<pre>python setup.py install</pre>
<p>web.py安装算到此结束，如果想使用其中的db功能，还得借助与相应数据库操作模块，比如MySQLdb、psycopg2。如果需要尝试连接池(database pool)功能，还得装下DBUtils。这几个模块都可以通过easy_install来安装。</p>
<p>下面开始使用吧！</p>
<p><strong>1. 导入模块，定义数据库连接db。</strong></p>
<pre>import web
db = web.database(dbn='postgres', db='mydata', user='dbuser', pw='')</pre>
<p><strong>2. select 查询</strong></p>
<pre># 查询表
entries = db.select('mytable')

# where 条件
myvar = dict(name="Bob")
results = db.select('mytable', myvar, where="name = $name")
results = db.select('mytable', where="id&gt;100")

# 查询具体列
results = db.select('mytable', what="id,name")

# order by
results = db.select('mytable', order="post_date DESC")

# group
results = db.select('mytable', group="color")

# limit
results = db.select('mytable', limit=10)

# offset
results = db.select('mytable', offset=10)</pre>
<p><strong>3. 更新</strong></p>
<pre>db.update('mytable', where="id = 10", value1 = "foo")</pre>
<p><strong>4. 删除</strong></p>
<pre>db.delete('mytable', where="id=10")</pre>
<p><strong>5. 复杂查询</strong></p>
<pre># count
results = db.query("SELECT COUNT(*) AS total_users FROM users")
print results[0].total_users

# join
results = db.query("SELECT * FROM entries JOIN users WHERE entries.author_id = users.id")

# 防止SQL注入可以这么干
results = db.query("SELECT * FROM users WHERE id=$id", vars={'id':10})</pre>
<p><strong>6 多数据库操作 (web.py大于0.3)</strong></p>
<pre>db1 = web.database(dbn='mysql', db='dbname1', user='foo')
db2 = web.database(dbn='mysql', db='dbname2', user='foo')

print db1.select('foo', where='id=1')
print db2.select('bar', where='id=5')</pre>
<p><strong>7. 事务</strong></p>
<pre>t = db.transaction()
try:
    db.insert('person', name='foo')
    db.insert('person', name='bar')
except:
    t.rollback()
    raise
else:
    t.commit()

# Python 2.5+ 可以用with
from __future__ import with_statement
with db.transaction():
    db.insert('person', name='foo')
    db.insert('person', name='bar')</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/226">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/226#comments">3 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/226&title=web.py 数据库操作指南">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/web-py" rel="tag">web.py</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/226/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Python(Stackless) + MongoDB Apache 日志(2G)分析</title>
		<link>http://chenxiaoyu.org/blog/archives/213</link>
		<comments>http://chenxiaoyu.org/blog/archives/213#comments</comments>
		<pubDate>Thu, 04 Mar 2010 01:49:34 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=213</guid>
		<description><![CDATA[为何选择Stackless？ http://www.stackless.com
Stackless可以简单的认为是Python一个增强版，最吸引眼球的非“微线程”莫属。微线程是轻量级的线程，与线程相比切换消耗的资源更小，线程内共享数据更加便捷。相比多线程代码更加简洁和可读。此项目是由EVE Online推出，在并发和性能上确实很强劲。安装和Python一样，可以考虑替换原系统Python。:)
为何选择MongoDB？ http://www.mongodb.org
可以在官网看到很多流行的应用采用MongoDB，比如sourceforge，github等。相比RDBMS有啥优势？首先在速度和性能上优势最为明显，不仅可以当作类似KeyValue数据库来使，还包含了一些数据库查询（Distinct、Group、随机、索引等特性）。再有一点特性就是：简单。不论是应用还是文档，还是第三方API，几乎略过一下就可以使用。不过有点遗憾的就是，存储的数据文件很大，超过正常数据的2-4倍之间。本文测试的Apache日志大小是2G，生产的数据文件有6G。寒&#8230;希望在新版里能有所缩身，当然这个也是明显的以空间换速度的后果。
本文除去上面提及到的两个软件，还需要安装pymongo模块。http://api.mongodb.org/python/
模块安装方式有源码编译和easy_install，这里就不再累赘。
1. 从Apache日志中分析出需要保存的资料，比如IP，时间，GET/POST，返回状态码等。
fmt_str  = '(?P&#60;ip&#62;[.\d]+) - - \[(?P&#60;time&#62;.*?)\] "(?P&#60;method&#62;.*?) (?P&#60;uri&#62;.*?) HTTP/1.\d" (?P&#60;status&#62;\d+) (?P&#60;length&#62;.*?) "(?P&#60;referere&#62;.*?)" "(?P&#60;agent&#62;.*?)"'
fmt_name = re.findall('\?P&#60;(.*?)&#62;', fmt_str)
fmt_re   = re.compile(fmt_str)
定义了一个正则用于提取每行日志的内容。fmt_name就是提取尖括号中间的变量名。
2. 定义MongoDB相关变量，包括需要存到collection名称。Connection采取的是默认Host和端口。
conn     = Connection()
apache   = conn.apache
logs     = apache.logs
3. 保存日志行
def make_line(line):
    m = fmt_re.search(line)
    if m:
 [...]]]></description>
			<content:encoded><![CDATA[<p><strong>为何选择Stackless？</strong> <a href="http://www.stackless.com" target="_blank">http://www.stackless.com</a></p>
<p>Stackless可以简单的认为是Python一个增强版，最吸引眼球的非“微线程”莫属。微线程是轻量级的线程，与线程相比切换消耗的资源更小，线程内共享数据更加便捷。相比多线程代码更加简洁和可读。此项目是由EVE Online推出，在并发和性能上确实很强劲。安装和Python一样，可以考虑替换原系统Python。:)</p>
<p><strong>为何选择MongoDB？</strong> <a href="http://www.mongodb.org" target="_blank">http://www.mongodb.org</a></p>
<p>可以在官网看到很多流行的应用采用MongoDB，比如sourceforge，github等。相比RDBMS有啥优势？首先在速度和性能上优势最为明显，不仅可以当作类似KeyValue数据库来使，还包含了一些数据库查询（Distinct、Group、随机、索引等特性）。再有一点特性就是：简单。不论是应用还是文档，还是第三方API，几乎略过一下就可以使用。不过有点遗憾的就是，存储的数据文件很大，超过正常数据的2-4倍之间。本文测试的Apache日志大小是2G，生产的数据文件有6G。寒&#8230;希望在新版里能有所缩身，当然这个也是明显的以空间换速度的后果。</p>
<p>本文除去上面提及到的两个软件，还需要安装pymongo模块。<a href="http://api.mongodb.org/python/" target="_blank">http://api.mongodb.org/python/</a></p>
<p>模块安装方式有源码编译和easy_install，这里就不再累赘。</p>
<p>1. 从Apache日志中分析出需要保存的资料，比如IP，时间，GET/POST，返回状态码等。</p>
<pre>fmt_str  = '(?P&lt;ip&gt;[.\d]+) - - \[(?P&lt;time&gt;.*?)\] "(?P&lt;method&gt;.*?) (?P&lt;uri&gt;.*?) HTTP/1.\d" (?P&lt;status&gt;\d+) (?P&lt;length&gt;.*?) "(?P&lt;referere&gt;.*?)" "(?P&lt;agent&gt;.*?)"'
fmt_name = re.findall('\?P&lt;(.*?)&gt;', fmt_str)
fmt_re   = re.compile(fmt_str)</pre>
<p>定义了一个正则用于提取每行日志的内容。fmt_name就是提取尖括号中间的变量名。</p>
<p>2. 定义MongoDB相关变量，包括需要存到collection名称。Connection采取的是默认Host和端口。</p>
<pre>conn     = Connection()
apache   = conn.apache
logs     = apache.logs</pre>
<p>3. 保存日志行</p>
<pre>def make_line(line):
    m = fmt_re.search(line)
    if m:
        logs.insert(dict(zip(fmt_name, m.groups())))</pre>
<p>4. 读取Apache日志文件</p>
<pre>def make_log(log_path):
    with open(log_path) as fp:
        for line in fp:
            make_line(line.strip())</pre>
<p>5. 运行把。</p>
<pre>if __name__ == '__main__':
    make_log('d:/apachelog.txt')</pre>
<p>脚本大致情况如此，这里没有放上stackless部分代码，可以参考下面代码：</p>
<pre>import stackless
def print_x(x):
    print x
stackless.tasklet(print_x)('one')
stackless.tasklet(print_x)('two')
stackless.run()</pre>
<p>tasklet操作只是把类似操作放入队列中，run才是真正的运行。这里主要用于替换原有多线程threading并行分析多个日志的行为。</p>
<p><strong>补充：</strong></p>
<p>Apache日志大小是2G，671万行左右。生成的数据库有6G。</p>
<p>硬件：Intel(R) Core(TM)2 Duo CPU E7500 @ 2.93GHz 台式机</p>
<p>系统：RHEL 5.2 文件系统ext3</p>
<p>其他：Stackless 2.6.4 MongoDB 1.2</p>
<p>在保存300万左右时候，一切正常。不管是CPU还是内存，以及插入速度都很不错，大概有8-9000条/秒。和以前笔记本上测试结果基本一致。再往以后，内存消耗有点飙升，插入速度也降低。500万左右记录时候CPU达到40%，内存消耗2.1G。在生成第二个2G数据文件时候似乎速度和效率又提升上去了。最终保存的结果不是太满意。</p>
<p>后加用笔记本重新测试了一下1000万数据，速度比上面的671万明显提升很多。初步怀疑有两个地方可能会影响性能和速度：</p>
<p>1. 文件系统的差异。笔记本是Ubuntu 9.10，ext4系统。搜了下ext3和ext4在大文件读写上会有所差距。</p>
<p>2. 正则匹配上。单行操作都是匹配提取。大文件上应该还有优化的空间。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/213">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/213#comments">6 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/213&title=Python(Stackless) + MongoDB Apache 日志(2G)分析">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/apache" rel="tag">Apache</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/mongodb" rel="tag">MongoDB</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/213/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PostgreSQL UUID 函数</title>
		<link>http://chenxiaoyu.org/blog/archives/209</link>
		<comments>http://chenxiaoyu.org/blog/archives/209#comments</comments>
		<pubDate>Fri, 26 Feb 2010 07:10:45 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=209</guid>
		<description><![CDATA[测试环境：PostgreSQL 8.4
默认PostgreSQL是木有UUID函数可使用，而不像MySQL提供uuid()函数，不过在contrib里有，只需要导入一下uuid-ossp.sql即可。（PS：注意权限问题，要Pg可读改文件。）
导入很简单，下面是win下面测试，其他平台类似该操作：
D:\&#62;psql -U postgres -h localhost -f D:\PostgreSQL\8.4\share\contrib\uuid-ossp.sql
Password for user postgres:
SET
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
进入psql，执行：
postgres=# select uuid_generate_v1();
           uuid_generate_v1
--------------------------------------
 86811bd4-22a5-11df-b00e-ebd863f5f8a7
(1 row)

postgres=# select uuid_generate_v4();
           uuid_generate_v4
--------------------------------------
 5edbfcbb-1df8-48fa-853f-7917e4e346db
(1 row)
主要就是uuid_generate_v1和uuid_generate_v4，当然还有uuid_generate_v3和uuid_generate_v5。其他使用可以参见PostgreSQL官方文档 uuid-ossp。

© smallfish for smallfish [...]]]></description>
			<content:encoded><![CDATA[<p>测试环境：PostgreSQL 8.4</p>
<p>默认PostgreSQL是木有UUID函数可使用，而不像MySQL提供uuid()函数，不过在contrib里有，只需要导入一下uuid-ossp.sql即可。（PS：注意权限问题，要Pg可读改文件。）</p>
<p>导入很简单，下面是win下面测试，其他平台类似该操作：</p>
<pre>D:\&gt;psql -U postgres -h localhost -f D:\PostgreSQL\8.4\share\contrib\uuid-ossp.sql
Password for user postgres:
SET
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION</pre>
<p>进入psql，执行：</p>
<pre>postgres=# select uuid_generate_v1();
           uuid_generate_v1
--------------------------------------
 86811bd4-22a5-11df-b00e-ebd863f5f8a7
(1 row)

postgres=# select uuid_generate_v4();
           uuid_generate_v4
--------------------------------------
 5edbfcbb-1df8-48fa-853f-7917e4e346db
(1 row)</pre>
<p>主要就是uuid_generate_v1和uuid_generate_v4，当然还有uuid_generate_v3和uuid_generate_v5。其他使用可以参见PostgreSQL官方文档 <a href="http://www.postgresql.org/docs/8.3/static/uuid-ossp.html" target="_blank">uuid-ossp</a>。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/209">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/209#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/209&title=PostgreSQL UUID 函数">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/postgresql" rel="tag">PostgreSQL</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/209/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PostgreSQL RPM 安装笔记</title>
		<link>http://chenxiaoyu.org/blog/archives/197</link>
		<comments>http://chenxiaoyu.org/blog/archives/197#comments</comments>
		<pubDate>Sat, 06 Feb 2010 02:21:23 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=197</guid>
		<description><![CDATA[测试环境：REHL 5.3
PostgreSQL版本：8.4.2
1. 首先检查下是否已经有PostgreSQL安装程序(俺的机器有pg-libs 8.1，无视之)

shell&#62; rpm -qa &#124; grep postgres

2. 下载最新的8.4.2RPM安装包，这个FTP速度挺快的。:)

shell&#62; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-server-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&#62; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-contrib-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&#62; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-libs-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&#62; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-devel-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&#62; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&#62; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-plpython-8.4.2-1PGDG.rhel5.x86_64.rpm

3. 安装PostgreSQL(要注意下顺序)，首先需要更新pg-libs版本。
后面几个不需要的话可以不装。主要是一些扩展功能。

shell&#62; rpm -ivh postgresql-libs-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&#62; rpm -ivh postgresql-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&#62; rpm -ivh postgresql-server-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&#62; rpm -ivh postgresql-contrib-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&#62; rpm -ivh postgresql-devel-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&#62; rpm -ivh postgresql-plpython-8.4.2-1PGDG.rhel5.x86_64.rpm

4. RPM安装完后，需要初始化PostgreSQL库。service初次启动会提示。
如果是源码安装这个过程就是对应的initdb -D，指定data目录。RPM默认对应目录是/var/lib/pgsql/data。

shell&#62; service postgresql initdb

5. service启动PostgreSQL

shell&#62; service postgresql start

到上面这一步基本是安装完成了。下面的是修改数据库用户密码和登陆相关。
6. 切换到postgres用户，修改数据库密码。(注意系统用户和数据库用户密码是两个概念，虽然名字都叫postgres)
修改完需要重启数据库，这里咱不重启，等修改完认证配置再一起重启。

shell&#62; su - postgres
shell&#62; psql
postgres=# [...]]]></description>
			<content:encoded><![CDATA[<p>测试环境：REHL 5.3<br />
PostgreSQL版本：8.4.2</p>
<p>1. 首先检查下是否已经有PostgreSQL安装程序(俺的机器有pg-libs 8.1，无视之)</p>
<pre>
shell&gt; rpm -qa | grep postgres
</pre>
<p>2. 下载最新的8.4.2RPM安装包，这个FTP速度挺快的。:)</p>
<pre>
shell&gt; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-server-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&gt; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-contrib-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&gt; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-libs-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&gt; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-devel-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&gt; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&gt; wget http://ftp.easynet.be/postgresql/binary/v8.4.2/linux/rpms/redhat/rhel-5-x86_64/postgresql-plpython-8.4.2-1PGDG.rhel5.x86_64.rpm
</pre>
<p>3. 安装PostgreSQL(要注意下顺序)，首先需要更新pg-libs版本。<br />
后面几个不需要的话可以不装。主要是一些扩展功能。</p>
<pre>
shell&gt; rpm -ivh postgresql-libs-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&gt; rpm -ivh postgresql-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&gt; rpm -ivh postgresql-server-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&gt; rpm -ivh postgresql-contrib-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&gt; rpm -ivh postgresql-devel-8.4.2-1PGDG.rhel5.x86_64.rpm
shell&gt; rpm -ivh postgresql-plpython-8.4.2-1PGDG.rhel5.x86_64.rpm
</pre>
<p>4. RPM安装完后，需要初始化PostgreSQL库。service初次启动会提示。<br />
如果是源码安装这个过程就是对应的initdb -D，指定data目录。RPM默认对应目录是/var/lib/pgsql/data。</p>
<pre>
shell&gt; service postgresql initdb
</pre>
<p>5. service启动PostgreSQL</p>
<pre>
shell&gt; service postgresql start
</pre>
<p>到上面这一步基本是安装完成了。下面的是修改数据库用户密码和登陆相关。</p>
<p>6. 切换到postgres用户，修改数据库密码。(注意系统用户和数据库用户密码是两个概念，虽然名字都叫postgres)<br />
修改完需要重启数据库，这里咱不重启，等修改完认证配置再一起重启。</p>
<pre>
shell&gt; su - postgres
shell&gt; psql
postgres=# ALTER USER postgres WITH PASSWORD '123456';
postgres=# \q
</pre>
<p>7. 修改认证文件/var/lib/pgsql/data/pg_hba.conf，登陆使用密码。md5格式。</p>
<pre>
shell&gt; vi /var/lib/pgsql/data/pg_hba.conf
修改ident为md5 (local, host)
</pre>
<p>8. service重启PostgreSQL</p>
<pre>
shell&gt; service postgresql restart
</pre>
<p>9. 再次进入测试，应该会提示输入密码鸟 :)</p>
<pre>
shell&gt;psql -U postgres
</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/197">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/197#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/197&title=PostgreSQL RPM 安装笔记">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/postgresql" rel="tag">PostgreSQL</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/197/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL &amp; PostgreSQL 小命令对比</title>
		<link>http://chenxiaoyu.org/blog/archives/175</link>
		<comments>http://chenxiaoyu.org/blog/archives/175#comments</comments>
		<pubDate>Fri, 05 Feb 2010 04:24:36 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=175</guid>
		<description><![CDATA[对比下一些两个数据库常用的操作。分别使用自带的client程序。
MySQL命令行：
mysql -u 用户名 -h 主机地址 -P 端口号 数据库名 -p
PostgreSQL命令行：
psql -U 用户名 -h 主机地址 -p 端口号 数据库名
操作对比：
mysql                      psql

SHOW DATABASES;           \l
USE db-name;     [...]]]></description>
			<content:encoded><![CDATA[<p>对比下一些两个数据库常用的操作。分别使用自带的client程序。</p>
<p>MySQL命令行：</p>
<pre>mysql -u 用户名 -h 主机地址 -P 端口号 数据库名 -p</pre>
<p>PostgreSQL命令行：</p>
<pre>psql -U 用户名 -h 主机地址 -p 端口号 数据库名</pre>
<p>操作对比：</p>
<pre>mysql                      psql

SHOW DATABASES;           \l
USE db-name;              \c db-name
SHOW TABLES;              \d
SHOW USERS;               \du
SHOW COLUMNS;             \d table-name
SHOW PROCESSLIST;         SELECT * FROM pg_stat_activity;
SELECT now()\G            \x 可以打开和关闭类似\G功能
SOURCE /path.sql          \i /path.sql
LOAD DATA INFILE ...      \copy ...
\h                        \?</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2010. |
<a href="http://chenxiaoyu.org/blog/archives/175">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/175#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/175&title=MySQL &#038; PostgreSQL 小命令对比">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/mysql" rel="tag">MySQL</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/postgresql" rel="tag">PostgreSQL</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/175/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PostgreSQL Partitioning 表分区</title>
		<link>http://chenxiaoyu.org/blog/archives/151</link>
		<comments>http://chenxiaoyu.org/blog/archives/151#comments</comments>
		<pubDate>Tue, 22 Dec 2009 08:20:12 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=151</guid>
		<description><![CDATA[测试版本：pg 8.3 (ubuntu)
在pg里表分区是通过表继承来实现的，一般都是建立一个主表，里面是空，然后每个分区都去继承它。
创建表分区步骤如下：
1. 创建主表
CREATE TABLE users ( uid int not null primary key, name varchar(20));
2. 创建分区表(必须继承上面的主表)
CREATE TABLE users_0 ( check (uid &#62;= 0 and uid&#60; 100) ) INHERITS (users);
CREATE TABLE users_1 ( check (uid &#62;= 100)) INHERITS (users);
3. 在分区表上建立索引，其实这步可以省略的哦
CREATE INDEX users_0_uidindex on users_0(uid);
CREATE INDEX users_1_uidindex on users_1(uid);
4. 创建规则RULE
CREATE RULE users_insert_0 AS
    ON [...]]]></description>
			<content:encoded><![CDATA[<p>测试版本：pg 8.3 (ubuntu)</p>
<p>在pg里表分区是通过表继承来实现的，一般都是建立一个主表，里面是空，然后每个分区都去继承它。</p>
<p>创建表分区步骤如下：</p>
<p>1. 创建主表</p>
<pre>CREATE TABLE users ( uid int not null primary key, name varchar(20));</pre>
<p>2. 创建分区表(必须继承上面的主表)</p>
<pre>CREATE TABLE users_0 ( check (uid &gt;= 0 and uid&lt; 100) ) INHERITS (users);
CREATE TABLE users_1 ( check (uid &gt;= 100)) INHERITS (users);</pre>
<p>3. 在分区表上建立索引，其实这步可以省略的哦</p>
<pre>CREATE INDEX users_0_uidindex on users_0(uid);
CREATE INDEX users_1_uidindex on users_1(uid);</pre>
<p>4. 创建规则RULE</p>
<pre>CREATE RULE users_insert_0 AS
    ON INSERT TO users WHERE
        (uid &gt;= 0 and uid &lt; 100)
    DO INSTEAD
        INSERT INTO users_0 VALUES (NEW.uid,NEW.name);

CREATE RULE users_insert_1 AS
    ON INSERT TO users WHERE
        (uid &gt;= 100)
    DO INSTEAD
        INSERT INTO users_1 VALUES (NEW.uid,NEW.name);</pre>
<p>下面就可以测试写入数据啦：</p>
<pre>postgres=# INSERT INTO users VALUES (100,'smallfish');
INSERT 0 0
postgres=# INSERT INTO users VALUES (20,'aaaaa');
INSERT 0 0
postgres=# select * from users;
uid  |   name
-----+-----------
20   | aaaaa
100  | smallfish
(2 笔资料列)
postgres=# select * from users_0;
uid  | name
-----+-------
20   | aaaaa
(1 笔资料列)

postgres=# select * from users_1;
uid  |   name
-----+-----------
100  | smallfish
(1 笔资料列)</pre>
<p>到这里表分区已经可以算完了，不过还有个地方需要修改下，先看count查询把。</p>
<pre>postgres=# EXPLAIN SELECT count(*) FROM users where uid&lt;100;
QUERY PLAN
------------------------------------------------
Aggregate  (cost=62.75..62.76 rows=1 width=0)
    -&gt;  Append  (cost=6.52..60.55 rows=879 width=0)
    -&gt;  Bitmap Heap Scan on users  (cost=6.52..20.18 rows=293 width=0)
Recheck Cond: (uid &lt; 100)
    -&gt;  Bitmap Index Scan on users_pkey  (cost=0.00..6.45 rows=293 width=0)
Index Cond: (uid &lt; 100)
    -&gt;  Bitmap Heap Scan on users_0 users  (cost=6.52..20.18 rows=293 width=0)
Recheck Cond: (uid &lt; 100)
    -&gt;  Bitmap Index Scan on users_0_uidindex  (cost=0.00..6.45 rows=293 width=0)
Index Cond: (uid &lt; 100)
    -&gt;  Bitmap Heap Scan on users_1 users  (cost=6.52..20.18 rows=293 width=0)
Recheck Cond: (uid &lt; 100)
    -&gt;  Bitmap Index Scan on users_1_uidindex  (cost=0.00..6.45 rows=293 width=0)
Index Cond: (uid &lt; 100)
(14 笔资料列)</pre>
<p>按照本来想法，uid小于100，理论上应该只是查询users_0表，通过EXPLAIN可以看到其他他扫描了所有分区的表。</p>
<pre>postgres=# SET constraint_exclusion = on;
SET
</pre>
<pre>
postgres=# EXPLAIN SELECT count(*) FROM users where uid&lt;100;
QUERY PLAN
------------------------------------------------
Aggregate  (cost=41.83..41.84 rows=1 width=0)
    -&gt;  Append  (cost=6.52..40.37 rows=586 width=0)
    -&gt;  Bitmap Heap Scan on users  (cost=6.52..20.18 rows=293 width=0)
Recheck Cond: (uid &lt; 100)
    -&gt;  Bitmap Index Scan on users_pkey  (cost=0.00..6.45 rows=293 width=0)
Index Cond: (uid &lt; 100)
    -&gt;  Bitmap Heap Scan on users_0 users  (cost=6.52..20.18 rows=293 width=0)
Recheck Cond: (uid &lt; 100)
    -&gt;  Bitmap Index Scan on users_0_uidindex  (cost=0.00..6.45 rows=293 width=0)
Index Cond: (uid &lt; 100)
(10 笔资料列)</pre>
<p>到这里整个过程都OK啦！</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/151">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/151#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/151&title=PostgreSQL Partitioning 表分区">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/postgresql" rel="tag">PostgreSQL</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/151/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PostgreSQL tablespace 表空间</title>
		<link>http://chenxiaoyu.org/blog/archives/146</link>
		<comments>http://chenxiaoyu.org/blog/archives/146#comments</comments>
		<pubDate>Tue, 22 Dec 2009 07:59:52 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=146</guid>
		<description><![CDATA[pgsql允许管理员在文件系统里定义表空间存储位置，这样创建数据库对象时候就可以引用这个表空间了。好处就不用多说了，可以把数据库对象存储到不同的分区上，比如更好的存储之类。默认initdb之后会有两个表空间pg_global和pg_default。
查看pgsql当前表空间有哪些可以试试下面：

postgres=&#62; SELECT spcname FROM pg_tablespace;
  spcname
------------
 pg_default
 pg_global
(2 rows)

或：

postgres=&#62; \db
    Name    &#124;  Owner   &#124; Location
------------+----------+----------
 pg_default &#124; postgres &#124;
 pg_global  &#124; postgres &#124;

建立表空间需要注意的主要的是权限问题，而且要在新的空目录上建立，权限属于数据库管理员比如默认postgres。
1. 建立目录

$ mkdir /home/smallfish/pgdata
$ sudo chown -R postgres:postgres /home/smallfish/pgdata

2. 进入psql

$ psql -U postgres -h 192.168.0.122

如果权限没设置好下面语句会报错

postgres=&#62; CREATE TABLESPACE space1 LOCATION '/home/smallfish/pgdata';

建测试表

postgres=&#62; CREATE TABLE [...]]]></description>
			<content:encoded><![CDATA[<p>pgsql允许管理员在文件系统里定义表空间存储位置，这样创建数据库对象时候就可以引用这个表空间了。好处就不用多说了，可以把数据库对象存储到不同的分区上，比如更好的存储之类。默认initdb之后会有两个表空间pg_global和pg_default。</p>
<p>查看pgsql当前表空间有哪些可以试试下面：</p>
<pre>
postgres=&gt; SELECT spcname FROM pg_tablespace;
  spcname
------------
 pg_default
 pg_global
(2 rows)
</pre>
<p>或：</p>
<pre>
postgres=&gt; \db
    Name    |  Owner   | Location
------------+----------+----------
 pg_default | postgres |
 pg_global  | postgres |
</pre>
<p>建立表空间需要注意的主要的是权限问题，而且要在新的空目录上建立，权限属于数据库管理员比如默认postgres。</p>
<p>1. 建立目录</p>
<pre>
$ mkdir /home/smallfish/pgdata
$ sudo chown -R postgres:postgres /home/smallfish/pgdata
</pre>
<p>2. 进入psql</p>
<pre>
$ psql -U postgres -h 192.168.0.122
</pre>
<p>如果权限没设置好下面语句会报错</p>
<pre>
postgres=&gt; CREATE TABLESPACE space1 LOCATION '/home/smallfish/pgdata';
</pre>
<p>建测试表</p>
<pre>
postgres=&gt; CREATE TABLE foo(i int) TABLESPACE space1;
</pre>
<p>可以查看表空间目录下多了文件</p>
<pre>
postgres=&gt; \! ls /home/smallfish/pgdata
</pre>
<p>删除表空间，需要注意的是先要删除所有该表空间里的对象</p>
<pre>
postgres=&gt; DROP TABLESPACE space1;
</pre>
<p>ok，到这里已经建立好表空间了。当然每次建表都指定TABLESPACE也有点麻烦，来点默认的把。</p>
<pre>
postgres=&gt; SET default_tablespace = space1;
postgres=&gt; CREATE TABLE foo(i int);
</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/146">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/146#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/146&title=PostgreSQL tablespace 表空间">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/postgresql" rel="tag">PostgreSQL</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/146/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C Apache Module 开发入门</title>
		<link>http://chenxiaoyu.org/blog/archives/140</link>
		<comments>http://chenxiaoyu.org/blog/archives/140#comments</comments>
		<pubDate>Wed, 16 Dec 2009 01:52:27 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Apache]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=140</guid>
		<description><![CDATA[前言：
扩展Apache模块开发网上大部分教程都是围绕Perl语言，老外的《Writing Apache Modules with Perl and C》可以算是经典之作了，可惜一直都是针对老版本开发，而且主力语言是Perl，C语言部分只是略有介绍。不过相比较而言用Perl来扩展模块功能确实比 C语言来的快速以及便捷多了，也简单容易。我自己也在工作里应用了一部分，主要是在防盗链上面写了两个简单都模块，可以参考我写的另外两篇文章：apache+mod_perl防盗链以及apache+mod_perl实现url rewrite。说了那么多题外话，回到正题，这里只是用C语言实现一个简单的hello模块，模块功能是查询MySQL自带mysql数据库里都user表。
系统环境：
ArchLinux Apache2.2 MySQL 5.0
具体开发步骤：
1. 利用Apache自带都apxs建立hello模块：
[root#localhost] apxs -g -n hello
这样就会在当前目录下新建一个hello模块的文件目录，可以看到里面有：Makefile mod_hello.c modules.mk这样的文件，具体apxs路径查询下本机apache/bin目录。
2. 预览下mod_hello.c，可以看到里面apxs自动帮你生成一堆代码了，我们需要的只是修改里面的代码部分，先简单都介绍下里面的函数说明。
include 部分就是引入了一些必要都头文件
hello_handler 这个就是hello模块都主体部分，所有的显示、处理请求什么的都在这里。
hello_register_hooks hello_module 这俩个是需要导出的函数所必须的，先可以不管他们，按照生成的不动即可。
3. 修改hello_handler函数，里面可以看到request_rec *r，r有很多函数和变量，具体要参见文档了。里面的ap_rputs是输出，可以简单的理解为把字符串输出到r。
static int hello_handler(request_rec *r)
{
if (strcmp(r-&#62;handler, "hello")) { // 判断apache配置文件里handler是否等于hello，不是就跳过
          return DECLINED;
     }
     r-&#62;content_type [...]]]></description>
			<content:encoded><![CDATA[<p><strong>前言：</strong></p>
<p>扩展Apache模块开发网上大部分教程都是围绕Perl语言，老外的《Writing Apache Modules with Perl and C》可以算是经典之作了，可惜一直都是针对老版本开发，而且主力语言是Perl，C语言部分只是略有介绍。不过相比较而言用Perl来扩展模块功能确实比 C语言来的快速以及便捷多了，也简单容易。我自己也在工作里应用了一部分，主要是在防盗链上面写了两个简单都模块，可以参考我写的另外两篇文章：<a href="http://chenxiaoyu.org/blog/archives/120" target="_blank">apache+mod_perl防盗链</a>以及<a href="http://chenxiaoyu.org/blog/archives/123" target="_blank">apache+mod_perl实现url rewrite</a>。说了那么多题外话，回到正题，这里只是用C语言实现一个简单的hello模块，模块功能是查询MySQL自带mysql数据库里都user表。</p>
<p><strong>系统环境：</strong></p>
<p>ArchLinux Apache2.2 MySQL 5.0</p>
<p><strong>具体开发步骤：</strong></p>
<p><strong>1. </strong>利用Apache自带都apxs建立hello模块：</p>
<pre>[root#localhost] apxs -g -n hello</pre>
<p>这样就会在当前目录下新建一个hello模块的文件目录，可以看到里面有：Makefile mod_hello.c modules.mk这样的文件，具体apxs路径查询下本机apache/bin目录。</p>
<p><strong>2.</strong> 预览下mod_hello.c，可以看到里面apxs自动帮你生成一堆代码了，我们需要的只是修改里面的代码部分，先简单都介绍下里面的函数说明。</p>
<p>include 部分就是引入了一些必要都头文件<br />
hello_handler 这个就是hello模块都主体部分，所有的显示、处理请求什么的都在这里。<br />
hello_register_hooks hello_module 这俩个是需要导出的函数所必须的，先可以不管他们，按照生成的不动即可。</p>
<p><strong>3. </strong>修改hello_handler函数，里面可以看到request_rec *r，r有很多函数和变量，具体要参见文档了。里面的ap_rputs是输出，可以简单的理解为把字符串输出到r。</p>
<pre>static int hello_handler(request_rec *r)
{
if (strcmp(r-&gt;handler, "hello")) { // 判断apache配置文件里handler是否等于hello，不是就跳过
          return DECLINED;
     }
     r-&gt;content_type = "text/html"; // 设置content-type
     if (!r-&gt;header_only)
          ap_rputs("The sample page from mod_hello.c\n", r); // 输出一段文字
     return OK;// 返回 200 OK状态
}</pre>
<p>增加#include &#8220;mysq.h&#8221;，查询需要用到这个头文件。<br />
具体代码参见本文结尾部分。</p>
<p><strong>4. </strong>编译模块</p>
<pre>[root#localhost] apxs -c -a -i -I/usr/include/mysql/ -lmysqlclient mod_hello.c</pre>
<p>可以看到一堆编译指令，加上-I和-l是编译mysql必须的，编译完会自动在httpd.conf加上 LoadModule hello_module modules/mod_hello.so</p>
<p><strong>5.</strong> 修改httpd.conf<br />
&lt;Location /hello&gt;<br />
SetHandler hello<br />
&lt;/Location<br />
<strong>6. </strong>重启apache，访问http://localhost/hello，看是否成功。</p>
<p>=====================</p>
<p>完整代码：</p>
<pre>#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
/* 头文件，本文用到了ap_rprintf函数 */
#include "apr.h"
#include "apr_lib.h"
#include "apr_strings.h"
#include "apr_want.h"
#include "mysql.h"

/* 定义mysql数据变量 */
const char *host = "localhost";
const char *user = "root";
const char *pass = "smallfish";
const char *db    = "mysql";

/* The sample content handler */
static int hello_handler(request_rec *r)
{
    if (strcmp(r-&gt;handler, "hello")) {
        return DECLINED;
    }
    r-&gt;content_type = "text/html";
    /* 定义mysql变量 */
    MYSQL mysql;
    MYSQL_RES *rs;
    MYSQL_ROW row;
    mysql_init(&amp;mysql); /* 初始化 */
    if (!mysql_real_connect(&amp;mysql, host, user, pass, db, 0, NULL, 0)) {/* 连接数据库 */
        ap_rprintf(r, "&lt;li&gt;Error:%d %s&lt;/li&gt;\n", mysql_errno(&amp;mysql), mysql_error(&amp;mysql));
        return OK;
    }
    char *sql = "select host,user from user order by rand()";
    if (mysql_query(&amp;mysql, sql)!=0) { /* 查询 */
        ap_rprintf(r, "&lt;li&gt;Error : %d %s&lt;/li&gt;\n", mysql_errno(&amp;mysql), mysql_error(&amp;mysql));
        return OK;
    }
    rs = mysql_store_result(&amp;mysql); /* 获取查询结果 */
    while ((row = mysql_fetch_row(rs))) { /* 获取每一行记录 */
        ap_rprintf(r, "&lt;li&gt;%s - %s&lt;/li&gt;\n", row[0], row[1]);
    }
    mysql_free_result(rs); /* 释放结果集 */
    mysql_close(&amp;mysql); /* 关闭连接 */
    return OK;
}

static void hello_register_hooks(apr_pool_t *p)
{
    ap_hook_handler(hello_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA hello_module = {
    STANDARD20_MODULE_STUFF,
    NULL,                            /* create per-dir              config structures */
    NULL,                            /* merge  per-dir              config structures */
    NULL,                            /* create per-server config structures */
    NULL,                            /* merge  per-server config structures */
    NULL,                            /* table of config file commands                 */
    hello_register_hooks  /* register hooks                                */
};</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/140">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/140#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/140&title=C Apache Module 开发入门">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/apache" rel="tag">Apache</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/140/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>修改 ModPython 下 PYTHON_EGG_CACHE 报错</title>
		<link>http://chenxiaoyu.org/blog/archives/137</link>
		<comments>http://chenxiaoyu.org/blog/archives/137#comments</comments>
		<pubDate>Wed, 16 Dec 2009 01:43:01 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=137</guid>
		<description><![CDATA[环境：Linux Apache Python(mod_python)
换了一台新机器，没有配置Mod_Python了，在一些应用里import MySQLdb出现了下面错误：
ExtractionError: Can't extract file(s) to egg cache
The following error occurred while trying to extract file(s) to the Python egg
cache:
  [Errno 13] Permission denied: '/root/.python-eggs'
The Python egg cache directory is currently set to:
  /root/.python-eggs
Perhaps your account does not have write access to this directory?  You can
change the cache directory by [...]]]></description>
			<content:encoded><![CDATA[<p>环境：Linux Apache Python(mod_python)</p>
<p>换了一台新机器，没有配置Mod_Python了，在一些应用里<strong>import MySQLdb</strong>出现了下面错误：</p>
<pre>ExtractionError: Can't extract file(s) to egg cache
The following error occurred while trying to extract file(s) to the Python egg
cache:
  [Errno 13] Permission denied: '/root/.python-eggs'
The Python egg cache directory is currently set to:
  /root/.python-eggs
Perhaps your account does not have write access to this directory?  You can
change the cache directory by setting the PYTHON_EGG_CACHE environment
variable to point to an accessible directory.</pre>
<p>解决办法有两种：</p>
<p>1.设置PYTHON_EGG_CACHE环境变量</p>
<pre>$ SetEnv PYTHON_EGG_CACHE /tmp/aaa/</pre>
<p>目录权限注意要是apache用户，或者简单点就777</p>
<p>2.把egg格式转成目录</p>
<pre>$ cd /python-path/site-packages/
$ mv MySQL_python-1.2.3c1-py2.5-linux-x86_64.egg foo.zip
$ mkdir MySQL_python-1.2.3c1-py2.5-linux-x86_64.egg
$ cd MySQL_python-1.2.3c1-py2.5-linux-x86_64.egg
$ unzip ../foo.zip
$ rm ../foo.zip</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/137">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/137#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/137&title=修改 ModPython 下 PYTHON_EGG_CACHE 报错">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/apache" rel="tag">Apache</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/137/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Java调用Linux SCP操作</title>
		<link>http://chenxiaoyu.org/blog/archives/131</link>
		<comments>http://chenxiaoyu.org/blog/archives/131#comments</comments>
		<pubDate>Wed, 16 Dec 2009 01:18:21 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=131</guid>
		<description><![CDATA[先来回顾下linux下scp命令的用法：
[shell $] scp -r /本地目录或文件 user@192.168.0.110:/远程目录
这条命令是把本地的目录或者文件拷贝到远程192.168.0.110一个目录下，如果是从远程拷到本地，则反一下ip和目录。-r则是递归目录。更多参见scp &#8211;help
最近在Java里调用scp，是通过一个JSP页面来触发。为了在调用系统命令时候不出现提示密码，两台机器配置好了信任关系，可以参考ssh, scp不输入密码，大致代码如下：
Runtime.getRuntime().exec("scp /aa.txt root@192.168.0.110:/bb");
try时候也没任何异常，但是文件没拷贝过去，最后根据Process的waitFor()获取命令返回值是1。
这下可以肯定的是调用系统命令失败，在System.out.println里打印出command，linux下运行是没错的。为何呢？
后来发现原来是用户权限的问题，默认apache运行用户是nobody，根本没权限调用scp命令，配置的信任关系也是本机的root用户。
那就重新加一个user把，adduser&#8230;到配置好信任关系，在scp -i 指定一个rsa文件，并把rsa文件复制到/tmp目录下，权限为0755，继续刷新，后台可以看到提示输入密码之类的output了。
貌似还比较棘手，最后还是搜了下，发现有关Java scp的库，Ganymed SSH-2 for Java。貌似比较老，先来测试一下把。
Connection conn = new Connection(“192.168.0.110”);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(“root”, "***********");
if (isAuthenticated == false)
    throw new IOException("Authentication failed.");
SCPClient client = new SCPClient(conn);
client.put("/aa.txt", "/bb");
conn.close();
OK！发现竟然可以一次运行了。算了就不调用系统命令了，直接使用这个库把。
client.put方法第一个参数可以是个数组，即文件名的数组。暂时没找到整个目录的方法，就自己手动获取下目录文件列表把。

© smallfish for smallfish logs, 2009. &#124;
Permalink &#124;
No comment &#124;
Add to
del.icio.us

Post tags: Java







Feed enhanced by Better Feed [...]]]></description>
			<content:encoded><![CDATA[<p>先来回顾下linux下scp命令的用法：</p>
<pre>[shell $] scp -r /本地目录或文件 user@192.168.0.110:/远程目录</pre>
<p>这条命令是把本地的目录或者文件拷贝到远程192.168.0.110一个目录下，如果是从远程拷到本地，则反一下ip和目录。-r则是递归目录。更多参见scp &#8211;help</p>
<p>最近在Java里调用scp，是通过一个JSP页面来触发。为了在调用系统命令时候不出现提示密码，两台机器配置好了信任关系，可以参考<a href="http://chenxiaoyu.org/blog/archives/133" target="_blank">ssh, scp不输入密码</a>，大致代码如下：</p>
<pre>Runtime.getRuntime().exec("scp /aa.txt root@192.168.0.110:/bb");</pre>
<p>try时候也没任何异常，但是文件没拷贝过去，最后根据Process的waitFor()获取命令返回值是1。</p>
<p>这下可以肯定的是调用系统命令失败，在System.out.println里打印出command，linux下运行是没错的。为何呢？</p>
<p>后来发现原来是用户权限的问题，默认apache运行用户是nobody，根本没权限调用scp命令，配置的信任关系也是本机的root用户。</p>
<p>那就重新加一个user把，adduser&#8230;到配置好信任关系，在scp -i 指定一个rsa文件，并把rsa文件复制到/tmp目录下，权限为0755，继续刷新，后台可以看到提示输入密码之类的output了。</p>
<p>貌似还比较棘手，最后还是搜了下，发现有关Java scp的库，<a href="http://www.ganymed.ethz.ch/ssh2/" target="_blank">Ganymed SSH-2 for Java</a>。貌似比较老，先来测试一下把。</p>
<pre>Connection conn = new Connection(“192.168.0.110”);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(“root”, "***********");
if (isAuthenticated == false)
    throw new IOException("Authentication failed.");
SCPClient client = new SCPClient(conn);
client.put("/aa.txt", "/bb");
conn.close();</pre>
<p>OK！发现竟然可以一次运行了。算了就不调用系统命令了，直接使用这个库把。</p>
<p>client.put方法第一个参数可以是个数组，即文件名的数组。暂时没找到整个目录的方法，就自己手动获取下目录文件列表把。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/131">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/131#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/131&title=Java调用Linux SCP操作">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/java" rel="tag">Java</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/131/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSH, SCP 不输入密码</title>
		<link>http://chenxiaoyu.org/blog/archives/133</link>
		<comments>http://chenxiaoyu.org/blog/archives/133#comments</comments>
		<pubDate>Wed, 16 Dec 2009 01:17:44 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[SSH]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=133</guid>
		<description><![CDATA[经常在不同linux机器之间互相scp拷文件，每次总是要输入密码才可行。
通过ssh-keygen生成公钥，在两台机器之间互相建立信任通道即可。假设本地机器client，远程机器为server。
1. 生成rsa keygen
[winter@client winter] $ ssh-keygen -b 1024 -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/winter/.ssh/id_rsa): &#60;Enter&#62;
Enter passphrase (empty for no passphrase): &#60;Enter&#62;
Enter same passphrase again: &#60;Enter&#62;
Your identification has been saved in /home/winter/.ssh/id_rsa.
Your public key has been saved in /home/winter/.ssh/id_rsa.pub.
The key fingerprint is:
33:d4:7b:9c:87:04:cf:14:40:22:6d:c7:15:78:97:6a winter@client
直接上面公钥和私钥存放地址可以直接回车，私钥密码可以直接回车，也可以输入。
2. 查看.ssh目录下了多私钥和公钥文件
[winter@client winter] $ ls .ssh/
id_rsa  [...]]]></description>
			<content:encoded><![CDATA[<p>经常在不同linux机器之间互相scp拷文件，每次总是要输入密码才可行。</p>
<p>通过ssh-keygen生成公钥，在两台机器之间互相建立信任通道即可。假设本地机器client，远程机器为server。</p>
<p>1. 生成rsa keygen</p>
<pre>[winter@client winter] $ ssh-keygen -b 1024 -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/winter/.ssh/id_rsa): &lt;Enter&gt;
Enter passphrase (empty for no passphrase): &lt;Enter&gt;
Enter same passphrase again: &lt;Enter&gt;
Your identification has been saved in /home/winter/.ssh/id_rsa.
Your public key has been saved in /home/winter/.ssh/id_rsa.pub.
The key fingerprint is:
33:d4:7b:9c:87:04:cf:14:40:22:6d:c7:15:78:97:6a winter@client</pre>
<p>直接上面公钥和私钥存放地址可以直接回车，私钥密码可以直接回车，也可以输入。</p>
<p>2. 查看.ssh目录下了多私钥和公钥文件</p>
<pre>[winter@client winter] $ ls .ssh/
id_rsa  id_rsa.pub  known_hosts</pre>
<p>3. 拷贝公钥到目标机器上，并改名成authorized_keys</p>
<p>首次scp命令时候还是会提示输入密码，还有是否继续链接的提示，以后</p>
<p>4. 测试ssh进入</p>
<pre>[winter@client winter] $ ssh 192.168.0.110</pre>
<p>5. ok，搞定！</p>
<pre>[winter@server winter] # it's ok!</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/133">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/133#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/133&title=SSH, SCP 不输入密码">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/ssh" rel="tag">SSH</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/133/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache 虚拟主机配置笔记</title>
		<link>http://chenxiaoyu.org/blog/archives/126</link>
		<comments>http://chenxiaoyu.org/blog/archives/126#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:36:44 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Apache]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=126</guid>
		<description><![CDATA[环境：Linux Apache2.2 （路径 /usr/local/apache）
步骤：
1. 修改 conf/httpd.conf，找到如下位置，去除 # 注释符

# Virtual hosts
Include conf/extra/httpd-vhosts.conf

2.修改 conf/extra/httpd-vhosts.conf

&#60;VirtualHost *:80&#62;
    ServerAdmin webmaster@aa.com
    DocumentRoot "/usr/aa"
    ServerName ww.aa.com
    ServerAlias ww.aa.com
    ErrorLog "logs/ww.aa.com-error_log"
    CustomLog "logs/ww.aa.com-access_log" common
&#60;/VirtualHost&#62;

注意CustomLog这行，默认给的配置是：&#8221;logs/dummy-host.example.com-access_log common&#8221;
这个其实是错误的，Apache启动时候会报错，common这个应该放在双引号外面：

Syntax error on line 32 of /usr/local/apache/conf/extra/httpd-vhosts.conf:
CustomLog takes two or three [...]]]></description>
			<content:encoded><![CDATA[<p>环境：Linux Apache2.2 （路径 /usr/local/apache）</p>
<p>步骤：</p>
<p>1. 修改 conf/httpd.conf，找到如下位置，去除 # 注释符</p>
<pre>
# Virtual hosts
Include conf/extra/httpd-vhosts.conf
</pre>
<p>2.修改 conf/extra/httpd-vhosts.conf</p>
<pre>
&lt;VirtualHost *:80&gt;
    ServerAdmin webmaster@aa.com
    DocumentRoot "/usr/aa"
    ServerName ww.aa.com
    ServerAlias ww.aa.com
    ErrorLog "logs/ww.aa.com-error_log"
    CustomLog "logs/ww.aa.com-access_log" common
&lt;/VirtualHost&gt;
</pre>
<p>注意CustomLog这行，默认给的配置是：&#8221;logs/dummy-host.example.com-access_log common&#8221;</p>
<p>这个其实是错误的，Apache启动时候会报错，common这个应该放在双引号外面：</p>
<pre>
Syntax error on line 32 of /usr/local/apache/conf/extra/httpd-vhosts.conf:
CustomLog takes two or three arguments, a file name, a custom log format string or format name, and an optional "env=" clause (see docs)
</pre>
<p>另外还有个问题，在Apache+Tomcat时候出现的，在配置好mod_jk之后，通过默认80端口访问jsp总会提示403禁止访问，纳闷了！后来 才发现是Directory配置问题，因为每个VirtualHost配置的目录不是默认的DocumentRoot目录，在Apache2以后对于权限 和安全有了更高的要求，所以必须手动配置下每个Directory属性。</p>
<pre>
&lt;Directory "/usr/aa"&gt;
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
&lt;/Directory&gt;
</pre>
<p>OK，到这里虚拟主机部分已经配置完成！</p>
<p>补充一点，加上日志按天保存，避免一个巨大无比的文件！</p>
<pre>
CustomLog "|/usr/local/apache/bin/rotatelogs /usr/local/apache/logs/ww.aa.com-access-%y%m%d.log 86400 480 " combined
</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/126">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/126#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/126&title=Apache 虚拟主机配置笔记">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/apache" rel="tag">Apache</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/126/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache Mod_Perl实现 URL Rewrite</title>
		<link>http://chenxiaoyu.org/blog/archives/123</link>
		<comments>http://chenxiaoyu.org/blog/archives/123#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:33:07 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=123</guid>
		<description><![CDATA[相信apache的mod_rewrite模块都很熟悉了，今天这儿换个思路，利用mod_perl来实现下，发现竟然是如此的简单！
首先得保证apache已经安装了mod_perl模块，具体安装配置可以看上一篇文章哦。
修改下http.conf配置，添加一下内容：

PerlTransHandler MyTrans # MyTrans 这个是自己添加的处理模块名

具体MyTrans.pm脚本如下：

package MyTrans;

use strict;
use Apache2::Const qw(DECLINED);

sub handler {
    my $r = shift;
    my $uri = $r-&#62;uri;
    my ($id) = ($url =~ m&#124;^/news/(.*)\.html&#124;);
    $r-&#62;uri("/news.php");
    $r-&#62;args("id=$id");
    return Apache2::Const::DECLINED;
}
1;

实现就是：/news/12345.html  =&#62; /news.php?id=12345

© smallfish for smallfish logs, 2009. &#124;
Permalink [...]]]></description>
			<content:encoded><![CDATA[<p>相信apache的mod_rewrite模块都很熟悉了，今天这儿换个思路，利用mod_perl来实现下，发现竟然是如此的简单！</p>
<p>首先得保证apache已经安装了mod_perl模块，具体安装配置可以看上一篇文章哦。</p>
<p>修改下http.conf配置，添加一下内容：</p>
<pre>
PerlTransHandler MyTrans # MyTrans 这个是自己添加的处理模块名
</pre>
<p>具体MyTrans.pm脚本如下：</p>
<pre>
package MyTrans;

use strict;
use Apache2::Const qw(DECLINED);

sub handler {
    my $r = shift;
    my $uri = $r-&gt;uri;
    my ($id) = ($url =~ m|^/news/(.*)\.html|);
    $r-&gt;uri("/news.php");
    $r-&gt;args("id=$id");
    return Apache2::Const::DECLINED;
}
1;
</pre>
<p>实现就是：/news/12345.html  =&gt; /news.php?id=12345</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/123">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/123#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/123&title=Apache Mod_Perl实现 URL Rewrite">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/apache" rel="tag">Apache</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/perl" rel="tag">Perl</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/123/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache Mod_Perl 防盗链</title>
		<link>http://chenxiaoyu.org/blog/archives/120</link>
		<comments>http://chenxiaoyu.org/blog/archives/120#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:31:15 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=120</guid>
		<description><![CDATA[大体思路是这样的，比如有 一个地址：http://www.aa.com/down/1.mp3，不幸搜索引擎或者迅雷扒到了，就无偿为他们奉献流量了。 但是假如在http://www.aa.com/down/1.mp3?key=123，key参数每天变化或者几分钟变化一次，在apache服务端校 验下这个参数，不正确则显示拒绝访问或者找不到的话，那样防盗链的效果就算达到了把。
modperl强大到可以任意应用apache内部API，官方地址是：http://perl.apache.org 。根据apache版本选择相应的modperl版本，现在大部分都apache2了，就选择modperl2把。具体安装配置可以看官方文档。
先建立/home/httpd/modperl/startup.pl(目录请自行修改)，内容如下：
use strict;

use lib qw(/home/httpd/modperl); # 把这个路径加入到perl lib路径

use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Connection ();
use Apache2::RequestUtil ();
use Apache2::ServerUtil ();
use Apache2::Log ();
use Apache2::Request ();

1;
部分本机httpd.conf配置：

LoadModule perl_module                modules/mod_perl.so
LoadModule apreq_module             modules/mod_apreq2.so
PerlPostConfigRequire /home/httpd/modperl/startup.pl
&#60;Location /down &#62;
    SetHandler modperl # 设置该目录交给modper处理
    PerlAccessHandler Down # Down是模块名称
    [...]]]></description>
			<content:encoded><![CDATA[<p>大体思路是这样的，比如有 一个地址：http://www.aa.com/down/1.mp3，不幸搜索引擎或者迅雷扒到了，就无偿为他们奉献流量了。 但是假如在http://www.aa.com/down/1.mp3?key=123，key参数每天变化或者几分钟变化一次，在apache服务端校 验下这个参数，不正确则显示拒绝访问或者找不到的话，那样防盗链的效果就算达到了把。</p>
<p>modperl强大到可以任意应用apache内部API，官方地址是：<a href="http://perl.apache.org/" target="_blank">http://perl.apache.org</a> 。根据apache版本选择相应的modperl版本，现在大部分都apache2了，就选择modperl2把。具体安装配置可以看官方文档。</p>
<p>先建立/home/httpd/modperl/startup.pl(目录请自行修改)，内容如下：</p>
<pre>use strict;

use lib qw(/home/httpd/modperl); # 把这个路径加入到perl lib路径

use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Connection ();
use Apache2::RequestUtil ();
use Apache2::ServerUtil ();
use Apache2::Log ();
use Apache2::Request ();

1;</pre>
<p>部分本机httpd.conf配置：</p>
<pre>
LoadModule perl_module                modules/mod_perl.so
LoadModule apreq_module             modules/mod_apreq2.so
PerlPostConfigRequire /home/httpd/modperl/startup.pl
&lt;Location /down &gt;
    SetHandler modperl # 设置该目录交给modper处理
    PerlAccessHandler Down # Down是模块名称
    PerlSetVar key 123 # 设置校验参数值
&lt;/Location&gt;
</pre>
<p>mod_apreq2.so这个模块需要安装Apache2::Request，具体安装：<a href="http://pyh7.spaces.live.com/blog/cns%2147D8D44208AC51E5%21128.entry" target="_blank">http://pyh7.spaces.live.com/blog/cns!47D8D44208AC51E5!128.entry</a></p>
<p>startup.pl文件一般modperl应用都有，加载一些常用库，可以在apache启动时预先载入，避免重复加载。</p>
<p>修改这些后可以重启下apache，看下logs/error_log里最后是否有mod_apreq和mod_perl字样，如果有就说明成功了。剩下都就是写校验的perl脚本了，/home/httpd/modperl/Down.pm，内容如下：</p>
<pre>
package Down;
use strict;
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Connection ();
use Apache2::RequestUtil ();
use Apache2::ServerUtil ();
use Apache2::Log ();
use Apache2::Const -compile =&gt; qw(OK FORBIDDEN);
use Apache2::Request ();

sub handler {
    my $r = shift;
    my $req = Apache2::Request-&gt;new($r);
    my $ip = $r-&gt;connection-&gt;remote_ip;
    my $k = $req-&gt;param('key') || ''; # 判断访问时是否带key参数
    my $key = $r-&gt;dir_config('key') || '123'; # 加载httpd.conf配置中的key值
    if ($key eq $k) { # 相等可以正常访问
        return Apache2::Const::OK;
    } else { # 否则显示拒绝访问
        my $s = Apache2::ServerUtil-&gt;server;
        $s-&gt;log_error("[$ip--------forbidden.]");
        return Apache2::Const::FORBIDDEN;
    }
}

1;
</pre>
<p>提示一下，以上两个perl脚本文件末尾记得加上1;</p>
<p>重启下apache。现在可以通过http://www.aa.com/down/1.mp3和http://www.aa.com/down /1.mp3?key=123测试下。可以看见不加参数拒绝访问了把。这里只是简单的判断，实际上可以根据日期或者IP加密生成一个字符串来判断。</p>
<p>写这个帖子完全是无意中搜索modperl应用时候发现了，具体可以参见：<br />
<a href="http://pyh7.spaces.live.com/blog/cns%2147D8D44208AC51E5%21140.entry" target="_blank">http://pyh7.spaces.live.com/blog/cns!47D8D44208AC51E5!140.entry</a></p>
<p>上面的文档已经写都很详细了，包括怎么安装modperl、Apache2::Request等模块以及配置apache的http.conf就不在累赘都重复了。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/120">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/120#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/120&title=Apache Mod_Perl 防盗链">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/apache" rel="tag">Apache</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/perl" rel="tag">Perl</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/120/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pexpect通过SSH执行远程命令</title>
		<link>http://chenxiaoyu.org/blog/archives/117</link>
		<comments>http://chenxiaoyu.org/blog/archives/117#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:26:53 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=117</guid>
		<description><![CDATA[pexpect是python一个模块，可以通过：easy_install pexpect 来安装。
这里主要是用pexpect执行ssh，查看远程uptime和df -h看硬盘状况。
#ssh_cmd.py
#coding:utf-8
import pexpect

def ssh_cmd(ip, user, passwd, cmd):
    ssh = pexpect.spawn('ssh %s@%s "%s"' % (user, ip, cmd))
    r = ''
    try:
        i = ssh.expect(['password: ', 'continue connecting (yes/no)?'])
        if i == [...]]]></description>
			<content:encoded><![CDATA[<p>pexpect是python一个模块，可以通过：easy_install pexpect 来安装。</p>
<p>这里主要是用pexpect执行ssh，查看远程uptime和df -h看硬盘状况。</p>
<pre>#ssh_cmd.py
#coding:utf-8
import pexpect

def ssh_cmd(ip, user, passwd, cmd):
    ssh = pexpect.spawn('ssh %s@%s "%s"' % (user, ip, cmd))
    r = ''
    try:
        i = ssh.expect(['password: ', 'continue connecting (yes/no)?'])
        if i == 0 :
            ssh.sendline(passwd)
        elif i == 1:
            ssh.sendline('yes')
    except pexpect.EOF:
        ssh.close()
    else:
        r = ssh.read()
        ssh.expect(pexpect.EOF)
        ssh.close()
    return r

hosts = '''
192.168.0.12:smallfish:1234:df -h,uptime
192.168.0.13:smallfish:1234:df -h,uptime
'''

for host in hosts.split("\n"):
    if host:
        ip, user, passwd, cmds = host.split(":")
        for cmd in cmds.split(","):
            print "-- %s run:%s --" % (ip, cmd)
            print ssh_cmd(ip, user, passwd, cmd)</pre>
<p>hosts数组格式是：主机IP:用户名:密码:命令 (多个命令用逗号, 隔开)<br />
可以看出打印出相应的结果了，可以拼成html发送mail看起来比较美观些咯！</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/117">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/117#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/117&title=Pexpect通过SSH执行远程命令">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/117/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Memcached Java &amp;&amp; Python Client API 共享</title>
		<link>http://chenxiaoyu.org/blog/archives/114</link>
		<comments>http://chenxiaoyu.org/blog/archives/114#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:24:22 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Memcached]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=114</guid>
		<description><![CDATA[用Python写了一个计划任务，定时更新Memcached中一个key值，写的很happy，几分钟搞定。
然后在Java Servlet测试，代码写的也很happy，编译 &#8211; 刷新，一气呵成。
然后发现值一直是null，再tail日志看看，异常不断：
com.danga.MemCached.MemCachedClient Mon Jul 20 09:37:04 CST 2009 - ++++ exception thrown while trying to get object from cache for key: test_num
 com.danga.MemCached.MemCachedClient Mon Jul 20 09:37:04 CST 2009 - 3
 com.danga.MemCached.NestedIOException: 3
 at com.danga.MemCached.MemCachedClient.get(MemCachedClient.java:1408)
 at com.danga.MemCached.MemCachedClient.get(MemCachedClient.java:1270)
晕倒，记得以前为了让两个语言实现API读写共享，手动去修改了两个的API包，实现了中文互读写。难不成今儿个还要手动去搞一把？
然后手动试了下：

shell&#62; telnet xxxxxx 11211
get test_num
VALUE test_num 4 2
23
经查证VALUE协议返回的是 key flags len \r\n value 这样的格式，大悟：原来flags不一样啊，Java里面对int型赋值以后flags是0，而Python里则不一样，两者序列化的东西不同啊。懒得去 折腾两者序列化有啥不同。来点直接的把。
然后打开Python Memcached API，大概578行_val_to_store_info方法里，可以看到flags部分，是根据变量类型进行定义的，isinstance(val, [...]]]></description>
			<content:encoded><![CDATA[<p>用Python写了一个计划任务，定时更新Memcached中一个key值，写的很happy，几分钟搞定。</p>
<p>然后在Java Servlet测试，代码写的也很happy，编译 &#8211; 刷新，一气呵成。</p>
<p>然后发现值一直是null，再tail日志看看，异常不断：</p>
<pre>com.danga.MemCached.MemCachedClient Mon Jul 20 09:37:04 CST 2009 - ++++ exception thrown while trying to get object from cache for key: test_num
 com.danga.MemCached.MemCachedClient Mon Jul 20 09:37:04 CST 2009 - 3
 com.danga.MemCached.NestedIOException: 3
 at com.danga.MemCached.MemCachedClient.get(MemCachedClient.java:1408)
 at com.danga.MemCached.MemCachedClient.get(MemCachedClient.java:1270)</pre>
<p>晕倒，记得以前为了让两个语言实现API读写共享，手动去修改了两个的API包，实现了中文互读写。难不成今儿个还要手动去搞一把？</p>
<p>然后手动试了下：</p>
<pre>
shell&gt; telnet xxxxxx 11211
get test_num
VALUE test_num 4 2
23</pre>
<p>经查证VALUE协议返回的是 key flags len \r\n value 这样的格式，大悟：原来flags不一样啊，Java里面对int型赋值以后flags是0，而Python里则不一样，两者序列化的东西不同啊。懒得去 折腾两者序列化有啥不同。来点直接的把。</p>
<p>然后打开Python Memcached API，大概578行_val_to_store_info方法里，可以看到flags部分，是根据变量类型进行定义的，isinstance(val, str) 如果是str则pass。</p>
<p>到这里就简单了，直接在py代码里：mc.set(&#8216;test_num&#8217;, str(num))</p>
<p>Java读取OK。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/114">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/114#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/114&title=Memcached Java &#038;&#038; Python Client API 共享">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/java" rel="tag">Java</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/memcached" rel="tag">Memcached</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/114/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mysqldumpslow 慢查询日志分析工具</title>
		<link>http://chenxiaoyu.org/blog/archives/111</link>
		<comments>http://chenxiaoyu.org/blog/archives/111#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:21:27 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=111</guid>
		<description><![CDATA[mysql自带的这个玩意挺好使的，可以对慢查询里的sql进行排序、计算等操作。
首先得配置my.cnf：

log_slow_queries = /path/slow.log # 定义log位置，注意要有写入的权限

具体的使法如下：

mysqldumpslow -s c -t 40 /path/slow.log

出来的结果是访问次数最多的40个sql，几个参数大概意思如下：

-t 显示多少条
-s 排序，默认是at。c是次数，t是时间，l是lock时间，r是返回结果。如果是ac，at，al，ar则是倒序
-g 可以用正则匹配部分语句

可以参考mysqldumpslow &#8211;help，通过这个工具可以看到哪些锁表，或者其他性能问题，还能看到某些SQL_NO_CACHE提示呢，去想办法优化把！

© smallfish for smallfish logs, 2009. &#124;
Permalink &#124;
No comment &#124;
Add to
del.icio.us

Post tags: MySQL







Feed enhanced by Better Feed from  Ozh
]]></description>
			<content:encoded><![CDATA[<p>mysql自带的这个玩意挺好使的，可以对慢查询里的sql进行排序、计算等操作。</p>
<p>首先得配置my.cnf：</p>
<pre>
log_slow_queries = /path/slow.log # 定义log位置，注意要有写入的权限
</pre>
<p>具体的使法如下：</p>
<pre>
mysqldumpslow -s c -t 40 /path/slow.log
</pre>
<p>出来的结果是访问次数最多的40个sql，几个参数大概意思如下：</p>
<pre>
-t 显示多少条
-s 排序，默认是at。c是次数，t是时间，l是lock时间，r是返回结果。如果是ac，at，al，ar则是倒序
-g 可以用正则匹配部分语句
</pre>
<p>可以参考mysqldumpslow &#8211;help，通过这个工具可以看到哪些锁表，或者其他性能问题，还能看到某些SQL_NO_CACHE提示呢，去想办法优化把！</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/111">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/111#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/111&title=mysqldumpslow 慢查询日志分析工具">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/mysql" rel="tag">MySQL</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/111/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perl 批量跳过 MySQL Slave 复制错误</title>
		<link>http://chenxiaoyu.org/blog/archives/107</link>
		<comments>http://chenxiaoyu.org/blog/archives/107#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:19:12 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=107</guid>
		<description><![CDATA[发现mysql slave服务器经常因为一些特殊字符或者符号产生的更新语句报错，整个同步也会因此而卡在那，最初的办法只是手动去出错的机器，执行下面三条sql语句，跳过错误即可。

slave stop;
set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
slave start;

一台slave机器用这样方法还行，多台就麻烦了，就顺手写了个简单的perl脚本，方便统一跳过错误，代码如下：

#!/usr/bin/env perl
use strict;
use warnings;

# get slave status
sub get_status {
    my ($ip, $usr, $pass) = @_;
    my $info = `mysql -u$usr -p$pass -h$ip -e 'show slave status\\G;'`;
    if (($info =~ /Slave_IO_Running: Yes/) &#38;&#38; ($info =~ /Slave_SQL_Running: No/)) {
     [...]]]></description>
			<content:encoded><![CDATA[<p>发现mysql slave服务器经常因为一些特殊字符或者符号产生的更新语句报错，整个同步也会因此而卡在那，最初的办法只是手动去出错的机器，执行下面三条sql语句，跳过错误即可。</p>
<pre>
slave stop;
set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
slave start;
</pre>
<p>一台slave机器用这样方法还行，多台就麻烦了，就顺手写了个简单的perl脚本，方便统一跳过错误，代码如下：</p>
<pre>
#!/usr/bin/env perl
use strict;
use warnings;

# get slave status
sub get_status {
    my ($ip, $usr, $pass) = @_;
    my $info = `mysql -u$usr -p$pass -h$ip -e 'show slave status\\G;'`;
    if (($info =~ /Slave_IO_Running: Yes/) &amp;&amp; ($info =~ /Slave_SQL_Running: No/)) {
        return 1;
    }
    return 0;
}
# mysql slave skip
sub slaveskip {
    my ($ip, $usr, $pass) = @_;
    print "slave error **\n";
    system("mysql -u$usr -p$pass -h$ip -e 'slave stop;'");
    system("mysql -u$usr -p$pass -h$ip -e 'set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;'");
    system("mysql -u$usr -p$pass -h$ip -e 'slave start;'");
}

my @hosts = qw/
192.168.0.101:root:tt1234
192.168.0.102:root: tt1234
192.168.0.103:root: tt1234
/;
foreach (@hosts) {
    my ($ip, $usr, $pass) = split ':';
    print "// ----- $ip\n";
    my $count = 1;
    while ($count &lt; 100000) {
        my $status = get_status($ip, $usr, $pass);
        print "i: $count status: $status\n";
        last if $status == 0;
        slaveskip($ip, $usr, $pass);
        select(undef, undef, undef, 0.1);
        $count++;
    }
    print "\n";
}

exit;
</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/107">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/107#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/107&title=Perl 批量跳过 MySQL Slave 复制错误">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/mysql" rel="tag">MySQL</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/perl" rel="tag">Perl</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/107/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSH Tunnel &amp;&amp; Memcached</title>
		<link>http://chenxiaoyu.org/blog/archives/103</link>
		<comments>http://chenxiaoyu.org/blog/archives/103#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:15:09 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Memcached]]></category>
		<category><![CDATA[SSH]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=103</guid>
		<description><![CDATA[最近一台服务器放进了移动机房，需要访问原电信机房一台Memcached服务器，Memcached服务是以内网形式启动。
依靠google大神，搜索出解决思路，在本地起一个SSH链接，通过本地一个端口实现对另外机器的映射或者叫做转发。
上周本来已经搞定，本周突发灵异事件，竟然不管了，最后百般尝试，完成结果如下：
移动机器IP：220.xxx.xxx.xxx 电信机器IP：155.xxx.xxx.xxx
在移动机器上执行：
shell &#62; ssh -N -f -L 11211:192.168.0.xxx:11211 root@155.xxx.xxx.xxx
11211:192.168.0.xxx:11211，格式为：本地端口:memcache启动的IP:端口
这里没有用RSA认证，就直接输入密码。-N 是不需要shell，-f 是程序后台执行，其他参数参见ssh &#8211;help。
shell &#62; ps aux
可以看见进程已经在了，下面开始测试代码。

&#62;&#62;&#62; import memcache
&#62;&#62;&#62; mc = memcache.Client(['127.0.0.1:11211'],debug=True)
&#62;&#62;&#62; print mc.get('name')

© smallfish for smallfish logs, 2009. &#124;
Permalink &#124;
No comment &#124;
Add to
del.icio.us

Post tags: Memcached, SSH







Feed enhanced by Better Feed from  Ozh
]]></description>
			<content:encoded><![CDATA[<p>最近一台服务器放进了移动机房，需要访问原电信机房一台Memcached服务器，Memcached服务是以内网形式启动。</p>
<p>依靠google大神，搜索出解决思路，在本地起一个SSH链接，通过本地一个端口实现对另外机器的映射或者叫做转发。</p>
<p>上周本来已经搞定，本周突发灵异事件，竟然不管了，最后百般尝试，完成结果如下：</p>
<p>移动机器IP：220.xxx.xxx.xxx 电信机器IP：155.xxx.xxx.xxx</p>
<p>在移动机器上执行：</p>
<pre>shell &gt; ssh -N -f -L 11211:192.168.0.xxx:11211 root@155.xxx.xxx.xxx</pre>
<p>11211:192.168.0.xxx:11211，格式为：本地端口:memcache启动的IP:端口<br />
这里没有用RSA认证，就直接输入密码。-N 是不需要shell，-f 是程序后台执行，其他参数参见ssh &#8211;help。</p>
<pre>shell &gt; ps aux</pre>
<p>可以看见进程已经在了，下面开始测试代码。</p>
<pre>
&gt;&gt;&gt; import memcache
&gt;&gt;&gt; mc = memcache.Client(['127.0.0.1:11211'],debug=True)
&gt;&gt;&gt; print mc.get('name')</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/103">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/103#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/103&title=SSH Tunnel &#038;&#038; Memcached">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/memcached" rel="tag">Memcached</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/ssh" rel="tag">SSH</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/103/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用 Perl 快速解析 Apache Log</title>
		<link>http://chenxiaoyu.org/blog/archives/100</link>
		<comments>http://chenxiaoyu.org/blog/archives/100#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:11:24 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=100</guid>
		<description><![CDATA[功能简述
统计出日志里一个或多个页面总共访问的次数，比如aa.jsp, bb.jsp这样页面分别多少次。
实现简述
Apache单个日志文件800M。
最初程序使用Python编写，按行来统计，分别使用in(最慢)和index方法去查找，然后使用了正则匹配，程序运行时间从最初的1分50多秒优化到1分10秒左右，参考了qyb博客中提到的gc.disable()，有了一定的提升，最终还是需要1分左右。
然后随意用了Perl写了一个，用了最土鳖的&#60;LOG&#62;这样的按行分析，最后正则匹配，然后++，速度竟然在40-50秒之间，惊叹！后来经过shucho指点，在正则部分采用了预编译，效果那是相当惊人！800M文件只用了7秒左右。卧槽！
程序片段
# --------------------------------------------------------------------
use strict;
use Benchmark;

my $LOG_FILE = '/usr/local/apache/logs/access.log';
# 下面qr部分起了关键作用，预编译了表达式
my @EXT_LIST = map {qr/$_/} qw{
aaServlet
bbServlet
};

my $startime = new Benchmark;
my %result;
map {$result{$_} = 0} @EXT_LIST;
open LOG_FILE, $LOG_FILE;
while (&#60;LOG_FILE&#62;){
    foreach my $ext (@EXT_LIST){
        $result{$ext}++ if $_ =~ /$ext/;
    }
}
close LOG_FILE;

while (my ($key, $value) = each(%result)){
 [...]]]></description>
			<content:encoded><![CDATA[<p><strong>功能简述</strong></p>
<p>统计出日志里一个或多个页面总共访问的次数，比如aa.jsp, bb.jsp这样页面分别多少次。</p>
<p><strong>实现简述</strong></p>
<p>Apache单个日志文件800M。</p>
<p>最初程序使用Python编写，按行来统计，分别使用in(最慢)和index方法去查找，然后使用了正则匹配，程序运行时间从最初的1分50多秒优化到1分10秒左右，参考了<a href="http://www.dup2.org/node/1006" target="_blank">qyb</a>博客中提到的gc.disable()，有了一定的提升，最终还是需要1分左右。</p>
<p>然后随意用了Perl写了一个，用了最土鳖的&lt;LOG&gt;这样的按行分析，最后正则匹配，然后++，速度竟然在40-50秒之间，惊叹！后来经过<a href="http://shucho.org/blog/" target="_blank">shucho</a>指点，在正则部分采用了预编译，效果那是相当惊人！800M文件只用了7秒左右。卧槽！</p>
<p><strong>程序片段</strong></p>
<pre># --------------------------------------------------------------------
use strict;
use Benchmark;

my $LOG_FILE = '/usr/local/apache/logs/access.log';
# 下面qr部分起了关键作用，预编译了表达式
my @EXT_LIST = map {qr/$_/} qw{
aaServlet
bbServlet
};

my $startime = new Benchmark;
my %result;
map {$result{$_} = 0} @EXT_LIST;
open LOG_FILE, $LOG_FILE;
while (&lt;LOG_FILE&gt;){
    foreach my $ext (@EXT_LIST){
        $result{$ext}++ if $_ =~ /$ext/;
    }
}
close LOG_FILE;

while (my ($key, $value) = each(%result)){
    $key =~ s/\(\?-xism:(.*?)\)/$1/g;
    print "$key:\t$value\n";
}

printf "** %s\n\n", timestr(timediff(new Benchmark, $startime));</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/100">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/100#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/100&title=使用 Perl 快速解析 Apache Log">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/apache" rel="tag">Apache</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/perl" rel="tag">Perl</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/100/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>emacs windows配置笔记</title>
		<link>http://chenxiaoyu.org/blog/archives/96</link>
		<comments>http://chenxiaoyu.org/blog/archives/96#comments</comments>
		<pubDate>Thu, 10 Dec 2009 08:53:41 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Editor]]></category>
		<category><![CDATA[Emacs]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=96</guid>
		<description><![CDATA[俺最新.emcas配置地址是：http://github.com/smallfish/editor/blob/master/emacs/.emacs
最近手痒，看到不少牛x人物都是用emacs，遂在windows下装一个玩玩。
下载地址：http://ftp.gnu.org/pub/gnu/emacs/windows/emacs-23.1-bin-i386.zip
解压到：D:\emacs-23.1
可以看到bin、etc、lisp等目录。主要运行都在bin目录。
runemacs.exe   这个就是运行文件拉，可以发送到桌面快捷方式。
可以运行一下addpm.exe这个，其作用就是把emacs加入到开始程序菜单里。
试着运行一下runemacs.exe，可以发现默认光标的位置，那是一个入门教程喔，还是中文的耶~
建议都看下这个入门的教程，常用的快捷键都有说明。
接下来加点常用的功能把，比如显示行号，goto line的功能。(俺也只配置了这个两项)
配置文件主要是_emacs或者.emacs，win下建议_emacs，点号开头的文件需要到cmd下才行。
_emacs文件放到哪儿呢？俺是直接修改了win注册表选项。
选项是：HKEY_CURRENT_USER\Software\GNU\Emacs，注意GNU\Emacs是需要新建的。接下来在Emacs里新建一个HOME项，值是你的emacs路径，比如我的：D:\emacs-23.1\bin。
然后需要做的就是把_emacs文件在这个bin目录下。
经过几经周折，显示行号和goto功能的配置如下：
(global-linum-mode 1)
(global-set-key [(meta g)] 'goto-line)
第一行是显示行号
第二行是设置meta+g转到goto功能，meta在windows下可以用alt来操作。
其他功能以后在后续补上，快捷键挺多，用了一会手指发酸。C-x 数字(1 2 3)挺好，可以开多窗口浏览了。

© smallfish for smallfish logs, 2009. &#124;
Permalink &#124;
One comment &#124;
Add to
del.icio.us

Post tags: Emacs







Feed enhanced by Better Feed from  Ozh
]]></description>
			<content:encoded><![CDATA[<p>俺最新.emcas配置地址是：<a href="http://github.com/smallfish/editor/blob/master/emacs/.emacs" target="_blank">http://github.com/smallfish/editor/blob/master/emacs/.emacs</a></p>
<p>最近手痒，看到不少牛x人物都是用emacs，遂在windows下装一个玩玩。</p>
<p>下载地址：<a href="http://ftp.gnu.org/pub/gnu/emacs/windows/emacs-23.1-bin-i386.zip" target="_blank">http://ftp.gnu.org/pub/gnu/emacs/windows/emacs-23.1-bin-i386.zip</a></p>
<p>解压到：D:\emacs-23.1</p>
<p>可以看到bin、etc、lisp等目录。主要运行都在bin目录。</p>
<p>runemacs.exe   这个就是运行文件拉，可以发送到桌面快捷方式。</p>
<p>可以运行一下addpm.exe这个，其作用就是把emacs加入到开始程序菜单里。</p>
<p>试着运行一下runemacs.exe，可以发现默认光标的位置，那是一个入门教程喔，还是中文的耶~</p>
<p>建议都看下这个入门的教程，常用的快捷键都有说明。</p>
<p>接下来加点常用的功能把，比如显示行号，goto line的功能。(俺也只配置了这个两项)</p>
<p>配置文件主要是_emacs或者.emacs，win下建议_emacs，点号开头的文件需要到cmd下才行。</p>
<p>_emacs文件放到哪儿呢？俺是直接修改了win注册表选项。</p>
<p>选项是：<strong>HKEY_CURRENT_USER\Software\GNU\Emacs</strong>，注意GNU\Emacs是需要新建的。接下来在Emacs里新建一个<strong>HOME</strong>项，值是你的emacs路径，比如我的：D:\emacs-23.1\bin。</p>
<p>然后需要做的就是把_emacs文件在这个bin目录下。</p>
<p>经过几经周折，显示行号和goto功能的配置如下：</p>
<pre>(global-linum-mode 1)
(global-set-key [(meta g)] 'goto-line)</pre>
<p>第一行是显示行号</p>
<p>第二行是设置meta+g转到goto功能，meta在windows下可以用alt来操作。</p>
<p>其他功能以后在后续补上，快捷键挺多，用了一会手指发酸。C-x 数字(1 2 3)挺好，可以开多窗口浏览了。</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/96">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/96#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/96&title=emacs windows配置笔记">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/emacs" rel="tag">Emacs</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/96/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>使用Git维护你的网站</title>
		<link>http://chenxiaoyu.org/blog/archives/90</link>
		<comments>http://chenxiaoyu.org/blog/archives/90#comments</comments>
		<pubDate>Tue, 08 Dec 2009 02:12:54 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=90</guid>
		<description><![CDATA[
简介
git是由Linus Torvalds编写的一个开放源码的版本控制系统. 它的主要目标是高度分散, 效率超过其他竞争对手.
我就是使用git维护本网站. 我知道git不应该这样的粗重任务的使用, 即每一个开发者维护一份代码拷贝, 但是它工作的很好, 所有我使用它.
本文的目的就是说明如何在家里或者笔记本里维护一个本地拷贝, 然后让这些修改提交到互联网主机上. 下面就是介绍如何设置.
安装
# Gentoo
emerge git
# Debian/Ubuntu
apt-get install git-core
# RedHat/Fedora
yum install git
初始化
你会进入你的服务器的目录和初始化git仓库.
# 进入你的web目录
cd /$wherever/html/
# 初始化仓库
git init
# 添加所有内容
git add .
# 提交 -m备注
git commit -a -m "The Initial Import."
然后返回你的html父目录, 克隆新的git-ized web目录.
# 返回你的html目录
cd ..
# 克隆你的web目录到 html.git
git clone --bare html html.git
现在你已经初始化好了仓库, 并将整个目录(递归)到该库中, 并进行了初次提交, 为web目录建立了一个git克隆. 这个git目录(html.git)是整个过程的关键.
获取一份开发环境的拷贝
1. 转到你的开发系统
2. 安装git
3. 从你的开发目录运行下面命令
git clone ssh://yoursite.com/path/to/html.git
现在已经获得一个完整的网站服务器版本的本地拷贝.
使你的web目录克隆Git目录
记住, 你的html.git是这里的关键, 而不是现有的html目录, 所以你要切换出来, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-92" title="git-tree" src="http://chenxiaoyu.org/wp-content/uploads/2009/12/git-tree.gif" alt="git-tree" width="263" height="316" /></p>
<p><strong>简介</strong></p>
<p>git是由<a href="http://en.wikipedia.org/wiki/Linus_Torvalds" target="_blank">Linus Torvalds</a>编写的一个开放源码的版本控制系统. 它的主要目标是高度分散, 效率超过其他竞争对手.</p>
<p>我就是使用git维护本网站. 我知道git不应该这样的粗重任务的使用, 即每一个开发者维护一份代码拷贝, 但是它工作的很好, 所有我使用它.</p>
<p>本文的目的就是说明如何在家里或者笔记本里维护一个本地拷贝, 然后让这些修改提交到互联网主机上. 下面就是介绍如何设置.</p>
<p><strong>安装</strong></p>
<pre># Gentoo
emerge git</pre>
<pre># Debian/Ubuntu
apt-get install git-core</pre>
<pre># RedHat/Fedora
yum install git</pre>
<p><strong>初始化</strong></p>
<p>你会进入你的服务器的目录和初始化git仓库.</p>
<pre># 进入你的web目录
cd /$wherever/html/</pre>
<pre># 初始化仓库
git init</pre>
<pre># 添加所有内容
git add .</pre>
<pre># 提交 -m备注
git commit -a -m "The Initial Import."</pre>
<p>然后返回你的html父目录, 克隆新的git-ized web目录.</p>
<pre># 返回你的html目录
cd ..</pre>
<pre># 克隆你的web目录到 html.git
git clone --bare html html.git</pre>
<p>现在你已经初始化好了仓库, 并将整个目录(递归)到该库中, 并进行了初次提交, 为web目录建立了一个git克隆. 这个git目录(html.git)是整个过程的关键.</p>
<p><strong>获取一份开发环境的拷贝</strong></p>
<p>1. 转到你的开发系统<br />
2. 安装git<br />
3. 从你的开发目录运行下面命令</p>
<pre>git clone ssh://yoursite.com/path/to/html.git</pre>
<p>现在已经获得一个完整的网站服务器版本的本地拷贝.</p>
<p>使你的web目录克隆Git目录</p>
<p>记住, 你的html.git是这里的关键, 而不是现有的html目录, 所以你要切换出来, 备份目录, 然后:</p>
<pre># 备份html目录, 然后克隆html.git
mv html html.backup; git clone html.git</pre>
<p>这在当前目录获取一份html.git的拷贝, 当然名字还是html. 这就是为什么备份旧的html目录.</p>
<p><strong>自动推送修改</strong></p>
<p>把你的html.git目录添加到post-update钩子中</p>
<pre>cd ../htdocs
env -i git pull</pre>
<p>修改钩子程序为可执行</p>
<pre>chmod +x post-update</pre>
<p><strong>在你的开发环境的变动 </strong></p>
<p>现在编辑的网站, 打开一个新的TextMate项目(你使用TextMate对吗?), 并拖动到html克隆目录. 整个结构都准备好了.</p>
<p>1. 通常的变动<br />
2. 保存更改<br />
3. 运行下面的程序, 例如(QuickSearchBox, TextMate等)</p>
<pre># This is for an OS X box
cd /Users/daniel/Development/html/
git commit -a -m "Another update."
git push</pre>
<p>这基本上是更新到git仓库最重要的两个命令: commit(注意:你的标记(如果想回滚的话))和push(推送到服务器).</p>
<p><strong>[根据你的操作系统和git安装, 你可能需要chmod +x 钩子程序, 然后再继续]</strong></p>
<p>现在你只需要激活post-update 钩子程序, 将会自动的获取web目录.</p>
<p>如果你在服务器端的操作基本也是相同的git commit和git push, 然后你的开发环境下git pull同步备份就可以了. 当然你还可以使用脚本, 如果你需要的话.</p>
<p>原文参见: <a href="http://danielmiessler.com/blog/using-git-to-maintain-your-website" target="_blank">http://danielmiessler.com/blog/using-git-to-maintain-your-website</a></p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/90">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/90#comments">3 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/90&title=使用Git维护你的网站">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/git" rel="tag">Git</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/90/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>tornado.database添加PooledDB连接池功能</title>
		<link>http://chenxiaoyu.org/blog/archives/82</link>
		<comments>http://chenxiaoyu.org/blog/archives/82#comments</comments>
		<pubDate>Tue, 01 Dec 2009 07:36:57 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[tornado]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=82</guid>
		<description><![CDATA[tornado.database模块简单包装了下对MySQL的操作，短小精悍。
无奈源码中无连接池功能，遂加上了一段DBUtils模块功能。
主要修改了reconnect()方法，大致在database.py第86行左右。(tornado 0.2 win版)
原代码如下：
    def reconnect(self):
        """Closes the existing database connection and re-opens it."""
        self.close()
        self._db = MySQLdb.connect(**self._db_args)
        self._db.autocommit(True)
修改后：
    def reconnect(self):
  [...]]]></description>
			<content:encoded><![CDATA[<p>tornado.database模块简单包装了下对MySQL的操作，短小精悍。</p>
<p>无奈源码中无连接池功能，遂加上了一段DBUtils模块功能。</p>
<p>主要修改了reconnect()方法，大致在database.py第86行左右。(tornado 0.2 win版)</p>
<p>原代码如下：</p>
<pre>    def reconnect(self):
        """Closes the existing database connection and re-opens it."""
        self.close()
        self._db = MySQLdb.connect(**self._db_args)
        self._db.autocommit(True)</pre>
<p>修改后：</p>
<pre>    def reconnect(self):
        """Closes the existing database connection and re-opens it."""
        self.close()
        try:
            from DBUtils import PooledDB
            pool_con = PooledDB.PooledDB(creator=MySQLdb, **self._db_args)
            self._db = pool_con.connection()
        except:
            self._db = MySQLdb.connect(**self._db_args)
            self._db.autocommit(True)</pre>
<p>至于安装DBUtils模块可以去<a href="http://pypi.python.org/pypi/DBUtils/" target="_blank">http://pypi.python.org/pypi/DBUtils/</a>下载，也可以简单的用easy_install：</p>
<pre>easy_install -U DBUtils</pre>
<p>PooledDB有这么几个参数：</p>
<pre>
* creator
    可以生成 DB-API 2 连接的任何函数或 DB-API 2 兼容的数据库连接模块。
* mincached
    启动时开启的空连接数量(缺省值 0 意味着开始时不创建连接)
* maxcached
    连接池使用的最多连接数量(缺省值 0 代表不限制连接池大小)
* maxshared
    最大允许的共享连接数量(缺省值 0 代表所有连接都是专用的)
* maxconnections
    最大允许连接数量(缺省值 0 代表不限制)
* blocking
    设置在达到最大数量时的行为(缺省值 0 或 False)
* maxusage
    单个连接的最大允许复用次数(缺省值 0 或 False 代表不限制的复用)
* setsession:
    一个可选的SQL命令列表用于准备每个会话，如 ["set datestyle to german", ...]
</pre>
<p>creator 函数或可以生成连接的函数可以接受这里传入的其他参数，例如主机名、数据库、用户名、密码等。你还可以选择传入creator函数的其他参数，允许失败重连和负载均衡。</p>
<p>具体可以参照下：<a href="http://www.webwareforpython.org/DBUtils/Docs/UsersGuide.zh.html" target="_blank">http://www.webwareforpython.org/DBUtils/Docs/UsersGuide.zh.html</a></p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/82">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/82#comments">6 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/82&title=tornado.database添加PooledDB连接池功能">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/tornado" rel="tag">tornado</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/82/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Pysvn 程序员指南</title>
		<link>http://chenxiaoyu.org/blog/archives/75</link>
		<comments>http://chenxiaoyu.org/blog/archives/75#comments</comments>
		<pubDate>Fri, 20 Nov 2009 09:31:48 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Pysvn]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=75</guid>
		<description><![CDATA[这是一篇关于pysvn模块的指南.
完整和详细的API请参考 pysvn Programmer&#8217;s Reference.
pysvn是操作Subversion版本控制的Python接口模块. 这个API接口可以管理一个工作副本, 查询档案库, 和同步两个.
该API不能创建新的仓库; 只能作用在现有仓库上. 如果你需要创建一个仓库, 请使用Subversion的svnadmin命令.
使用这个API, 你可以check out一份工作拷贝, 添加, 编辑, 和删除工作文件, 和check in, 比较, 或者放弃更改. 仓库属性, 如关键字扩展, 行字符结束, 或者忽略的列表也可以检查和控制.
Subversion 模型
Subversion是一个更新-编辑-提交的模型. 首先在本地建立一个工作副本. 在工作副本上进行修改, 最后提交到中央仓库 (可以是本地或者远程).
这个模型允许多人偶尔会同时修改同一个文件. 大多情况下. Subversion不会干预合并这些不同修改, 如果一个提交失败, 用户或者应用则要重新检查和修改然后再次提交.
常见任务
本节给出一些使用pysvn接口的常用例子. 业务可以会递归的处理目录. 添加参数recurse=False以防止这种行为; 例如, 你可以需要添加内容没有增加一个目录.

check out一份工作副本
import pysvn
client = pysvn.Client()
#check out the current version of the pysvn project
client.checkout('http://localhost/example/trunk',
    './examples/pysvn')
#check out revision 11 [...]]]></description>
			<content:encoded><![CDATA[<p>这是一篇关于pysvn模块的指南.</p>
<p>完整和详细的API请参考 <a href="http://pysvn.tigris.org/docs/pysvn_prog_ref.html" target="_blank">pysvn Programmer&#8217;s Reference</a>.</p>
<p>pysvn是操作Subversion版本控制的Python接口模块. 这个API接口可以管理一个工作副本, 查询档案库, 和同步两个.</p>
<p>该API不能创建新的仓库; 只能作用在现有仓库上. 如果你需要创建一个仓库, 请使用Subversion的svnadmin命令.</p>
<p>使用这个API, 你可以check out一份工作拷贝, 添加, 编辑, 和删除工作文件, 和check in, 比较, 或者放弃更改. 仓库属性, 如关键字扩展, 行字符结束, 或者忽略的列表也可以检查和控制.</p>
<p><strong>Subversion 模型</strong></p>
<p>Subversion是一个更新-编辑-提交的模型. 首先在本地建立一个工作副本. 在工作副本上进行修改, 最后提交到中央仓库 (可以是本地或者远程).</p>
<p>这个模型允许多人偶尔会同时修改同一个文件. 大多情况下. Subversion不会干预合并这些不同修改, 如果一个提交失败, 用户或者应用则要重新检查和修改然后再次提交.</p>
<p><strong>常见任务</strong></p>
<p>本节给出一些使用pysvn接口的常用例子. 业务可以会递归的处理目录. 添加参数recurse=False以防止这种行为; 例如, 你可以需要添加内容没有增加一个目录.<br />
<strong><br />
check out一份工作副本</strong></p>
<pre>import pysvn
client = pysvn.Client()
#check out the current version of the pysvn project
client.checkout('http://localhost/example/trunk',
    './examples/pysvn')
#check out revision 11 of the pysvn project
client.checkout('http://localhost/example/trunk',
   './examples/pysvn-11',
   revision=pysvn.Revision(pysvn.opt_revision_kind.number, 11))</pre>
<p>这是一个建立example测试项目的例子，目录是examples/pysvn. 这个项目是用在剩下的例子.</p>
<p><strong>添加一个文件或者目录到仓库</strong></p>
<pre>import pysvn
# write a file foo.txt
f = file('./examples/pysvn/foo.txt', 'w')
f.write('Sample versioned file via pithon\n')
f.close()
client = pysvn.Client()
#schedule the addition;
#  the working copy will now track the file as a scheduled change
client.add('./examples/pysvn/foo.txt')
#committing the change actually adds the file to the repository
client.checkin(['./examples/pysvn/foo.txt'], 'Adding a sample file')</pre>
<p>这个例子是在工作副本中创建了&#8217;foo.txt&#8217;文件, 然后添加到仓库. 请注意Client.import_()命令会同时增加和提交. 大多数应用, 会在许多修改后再提交.<br />
<strong><br />
更新工作副本</strong></p>
<pre>import pysvn
client = pysvn.Client()
client.update('./examples/pysvn')</pre>
<p>从仓库中更新其他用户修改并保存到本地副本. 大多数应用应该经常这样做以防止冲突.<br />
<strong><br />
提交更新到仓库</strong></p>
<pre>import pysvn
# edit the file foo.txt
f = open('./examples/pysvn/foo.txt', 'w')
f.write('Sample versioned file via python\n')
f.close()
# checkin the change with a log message
client = pysvn.Client()
client.checkin(['./examples/pysvn'], 'Corrected spelling of python in foo.txt')</pre>
<p>提交到Subversion是原子的. 要么所有修改都成功提交, 要么提交失败. 大部分应用会提交工作副本所有修改, 如本例所示, 或者通过个别文件或者目录, 但必须是同一单位.<br />
<strong><br />
放弃工作副本修改</strong></p>
<pre>import pysvn
# edit the file foo.txt
f = file('./examples/pysvn/foo.txt', 'w')
f.write('This change will never be seen\n')
f.close()
#discard the edits
client = pysvn.Client()
client.revert('./examples/pysvn/foo.txt')</pre>
<p>这丢弃在工作拷贝和恢复的文件或目录的任何未提交的未经编辑的状态变化.</p>
<p>正在计划增加或移除留无版本或恢复到工作拷贝.<br />
<strong><br />
重命名或者移动文件</strong></p>
<pre>import pysvn
client = pysvn.Client()
#rename the file client side
client.move('./examples/pysvn/foo.txt', './examples/pysvn/foo2.txt')
#checkin the change removes the file from the repository
client.checkin(['./examples/pysvn/foo.txt', './examples/pysvn/foo2.txt'], 'Foo has become Foo2')</pre>
<p>移动或重命名文件删除旧路径或名称的文件, 并增加了在新的位置, 同时保留以前的版本有关的信息.</p>
<p>在这个例子里, 我们通过文件名Client.checkin()传递父目录也将是有效的.</p>
<p>转移和合并可以在服务器端单步完成; 可以参见仓库任务的那节例子.<br />
<strong><br />
从仓库中删除文件或目录</strong></p>
<pre>import pysvn
client = pysvn.Client()
#schedule the removal;
#  the file will be removed from the working copy
client.remove('./examples/pysvn/foo2.txt')
#committing the change removes the file from the repository
client.checkin(['./examples/pysvn/foo2.txt'], 'Removing sample file')</pre>
<p>有些人把删除的文件, 或是用完全清除存储库目录. 该文件仍然存在于以前的版本, 可以通过检查或以其他方式进行审查以前修订的内容检索.<br />
<strong><br />
确定等待变动</strong></p>
<pre>import pysvn
client = pysvn.Client()
changes = client.status('./examples/pysvn')
print 'files to be added:'
print [f.path for f in changes if f.text_status == pysvn.wc_status_kind.added]
print 'files to be removed:'
print [f.path for f in changes if f.text_status == pysvn.wc_status_kind.deleted]
print 'files that have changed:'
print [f.path for f in changes if f.text_status == pysvn.wc_status_kind.modified]
print 'files with merge conflicts:'
print [f.path for f in changes if f.text_status == pysvn.wc_status_kind.conflicted]
print 'unversioned files:'
print [f.path for f in changes if f.text_status == pysvn.wc_status_kind.unversioned]</pre>
<p><strong>生成差异或补丁</strong></p>
<pre>import pysvn
client = pysvn.Client()
diff_text = client.diff('./tmp-file-prefix-', '.')</pre>
<p><strong>获取仓库URL</strong></p>
<pre>import pysvn
client = pysvn.Client()
entry = client.info('.')
print 'Url:',entry.url</pre>
<p><strong>仓库任务</strong></p>
<p>本节说明任务的例子, 操纵或检查仓库.虽然共同任务, 通过本地工作副本时间的变化, 这些任务直接影响到库<br />
获取仓库目录的清单</p>
<pre>import pysvn
client = pysvn.Client()
entry_list = client.ls('.')</pre>
<p><strong>从仓库获取文件内容</strong></p>
<pre>import pysvn
client = pysvn.Client()
file_content = client.cat('file.txt')</pre>
<p><strong>创建一个标记或分支</strong></p>
<pre>import pysvn
client = pysvn.Client()
log_message = "reason for change"
def get_log_message():
    return True, log_message
client.callback_get_log_message = get_log_message
client.copy('http://svnrepo.com/svn/trunk', 'http://svnrepo.com/svn/tag/%s' % tag_name )</pre>
<p><strong>从仓库中转移或者重命名</strong></p>
<pre>import pysvn
client = pysvn.Client()
client.move( 'file_old.txt', 'file_new.txt' )</pre>
<p><strong>锁定文件</strong></p>
<pre>import pysvn
client = pysvn.Client()
client.lock( 'file.txt', 'reason for locking' )</pre>
<p><strong>锁定文件并锁定其他用户或者工作副本</strong></p>
<pre>import pysvn
client = pysvn.Client()
client.lock( 'file.txt', 'reason for locking', force=True )</pre>
<p><strong>解锁</strong></p>
<pre>import pysvn
client = pysvn.Client()
client.unlock( 'file.txt' )</pre>
<p><strong>解锁文件并锁定其他用户或工作副本</strong></p>
<pre>import pysvn
client = pysvn.Client()
client.unlock( 'file.txt', force=True )</pre>
<p><strong>测试锁定文件</strong></p>
<p>Method 1:</p>
<pre>all_entries = self.client.info2( path, recurse=False )
for path, info in all_entries:
    if info['lock']:
        if info['lock']['token'] != '':
            print '%s is locked' % path
        print info['lock']['comment']</pre>
<p>Method 2:</p>
<pre>all_status = self.client.status( path, recurse=False, update=True )
for status in all_status:
    if status.entry is not None:
        if status.entry.lock_token is not None:
            print '%s is locked' % status.path</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/75">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/75#comments">One comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/75&title=Pysvn 程序员指南">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/pysvn" rel="tag">Pysvn</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/75/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cython参考指南 &#8211; 编译</title>
		<link>http://chenxiaoyu.org/blog/archives/60</link>
		<comments>http://chenxiaoyu.org/blog/archives/60#comments</comments>
		<pubDate>Thu, 19 Nov 2009 07:03:13 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Cython]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=60</guid>
		<description><![CDATA[Cython代码跟Python不一样，必须要编译。
编译经过两个阶段：
* Cython编译.pyx文件为.c文件
* C编译器会把.c文件编译成.so文件(Windows上是.pyd)
以下会分节介绍几种方式来建立你的扩展模块。
注意： -a 选项，如果使用该选项将会为.c文件生成一份很漂亮的HTML文件，双击高亮的章节部分会展开代码，这对理解，优化和调试模块将会非常有帮助。
命令行
从命令行执行Cython编译器，输入选项和.pyx文件列表。
$ cython -a yourmod.pyx
会生成一个yourmod.c文件（指定-a选项会生成一个HTML文件）
编译.c文件取决于你的操作系统，请参考下如何在你的系统写Python扩展模块文档。
下面是一个Linux系统的例子：
$ gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing \
 -I/usr/include/python2.5 -o yourmod.so yourmod.c
gcc需要提供包含的文件和扩展库的链接。
在目录里会生成yourmod.so文件。
现在只需要导入你的yourmod模块就可以了。

Distutils
确保你的系统已经安装好Distutils。
下面假设需要编译的文件叫hello.pyx。
建立一个setup.py的脚本：
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [Extension("hello", ["hello.pyx"])]

setup(
    name = ’Hello world app’,
    cmdclass = {’build_ext’: build_ext},
    ext_modules = ext_modules
)
在命令行执行：python setup.py [...]]]></description>
			<content:encoded><![CDATA[<p>Cython代码跟Python不一样，必须要编译。</p>
<p>编译经过两个阶段：</p>
<p>* Cython编译.pyx文件为.c文件</p>
<p>* C编译器会把.c文件编译成.so文件(Windows上是.pyd)</p>
<p>以下会分节介绍几种方式来建立你的扩展模块。</p>
<p>注意： -a 选项，如果使用该选项将会为.c文件生成一份很漂亮的HTML文件，双击高亮的章节部分会展开代码，这对理解，优化和调试模块将会非常有帮助。</p>
<p><strong>命令行</strong></p>
<p>从命令行执行Cython编译器，输入选项和.pyx文件列表。</p>
<pre>$ cython -a yourmod.pyx</pre>
<p>会生成一个yourmod.c文件（指定-a选项会生成一个HTML文件）</p>
<p>编译.c文件取决于你的操作系统，请参考下如何在你的系统写Python扩展模块文档。</p>
<p>下面是一个Linux系统的例子：</p>
<pre>$ gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing \
 -I/usr/include/python2.5 -o yourmod.so yourmod.c</pre>
<p>gcc需要提供包含的文件和扩展库的链接。</p>
<p>在目录里会生成yourmod.so文件。</p>
<p>现在只需要导入你的yourmod模块就可以了。<br />
<strong><br />
Distutils</strong></p>
<p>确保你的系统已经安装好Distutils。</p>
<p>下面假设需要编译的文件叫hello.pyx。</p>
<p>建立一个setup.py的脚本：</p>
<pre>from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [Extension("hello", ["hello.pyx"])]

setup(
    name = ’Hello world app’,
    cmdclass = {’build_ext’: build_ext},
    ext_modules = ext_modules
)</pre>
<p>在命令行执行：python setup.py build_ext &#8211;inplace</p>
<p>现在可以在shell或者脚本里正常导入使用了。<br />
<strong><br />
Pyximport</strong></p>
<p>在纯Python代码里调用Cython代码：</p>
<pre>&gt;&gt;&gt; import pyximport; pyximport.install()
&gt;&gt;&gt; import helloworld
Hello World</pre>
<p>这仅仅是简单调用Cython，不需要C库也不需要构建脚本。</p>
<p>当然也可以实验性的在Python调用。允许在Python模块中运行Cython代码在任何一个.pyx和.py模块。这包<br />
括标准库和包。如果Cython编译失败的话，pyximport会返回到加载失败的模块处。</p>
<p>.py安装是这样：</p>
<pre>&gt;&gt;&gt; pyximport.install(pyimport = True)</pre>
<p>原文：<a href="http://docs.cython.org/src/reference/compilation.html" target="_blank">http://docs.cython.org/src/reference/compilation.html</a></p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/60">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/60#comments">5 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/60&title=Cython参考指南 &#8211; 编译">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/cython" rel="tag">Cython</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/60/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Win Python Pyrex 扩展</title>
		<link>http://chenxiaoyu.org/blog/archives/53</link>
		<comments>http://chenxiaoyu.org/blog/archives/53#comments</comments>
		<pubDate>Tue, 17 Nov 2009 09:39:32 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=53</guid>
		<description><![CDATA[在偶的ubuntu里编写pyrex程序编译成so还是挺爽的，用 timeit.Timer 测试性能提升不少，今天在windows也尝试了一番。
需要的工具有：
- Pyrex http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
- Dev C++ http://www.bloodshed.net/devcpp.html
Pyrex 可以通过easy_install Pyrex来安装。
Dev C++ 安装完在系统环境变量Path里加上Dev C++安装目录/bin 目录。
测试扩展代码：
# file: foo.pyx
""" simple pyrex module """
cdef class Foo:
    """ foo doc ... """
    cdef char *name
    def __init__(self, name):
        self.name = name
    [...]]]></description>
			<content:encoded><![CDATA[<p>在偶的ubuntu里编写pyrex程序编译成so还是挺爽的，用 timeit.Timer 测试性能提升不少，今天在windows也尝试了一番。</p>
<p>需要的工具有：<br />
- Pyrex <a href="http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/" target="_blank">http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/</a><br />
- Dev C++ <a href="http://www.bloodshed.net/devcpp.html" target="_blank">http://www.bloodshed.net/devcpp.html</a></p>
<p>Pyrex 可以通过easy_install Pyrex来安装。<br />
Dev C++ 安装完在系统环境变量Path里加上Dev C++安装目录/bin 目录。</p>
<p>测试扩展代码：</p>
<pre># file: foo.pyx
""" simple pyrex module """
cdef class Foo:
    """ foo doc ... """
    cdef char *name
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return "foo names: %s" % (self.name)

# file: setup.py
from distutils.core import setup
from distutils.extension import Extension
from Pyrex.Distutils import build_ext

setup(
    name='foo', ext_modules=[Extension("foo", ["foo.pyx"])],
    cmdclass={'build_ext':build_ext}
)</pre>
<p>写好两个文件后，进入命令提示符：</p>
<pre>C:\&gt;python setup.py build_ext --inplace -c mingw32
running build_ext
pyrexc foo.pyx --&gt; foo.c
building 'foo' extension
creating build
creating build\temp.win32-2.5
creating build\temp.win32-2.5\Release
C:\Program Files\DEV-CPP\Bin\gcc.exe -mno-cygwin -mdll -O -Wall -ID:\Python25\include -ID:\Python25\PC -c foo.c -o build\temp.win32-2.5\Release\foo.o writing build\temp.win32-2.5\Release\foo.def C:\Program Files\DEV-CPP\Bin\dllwrap.exe -mno-cygwin -mdll -static --entry _DllMain@12 --output-lib build\temp.win32-2.5\Release\libfoo.a --def build\temp.win32-2.5\Release\foo.def -s build\temp.win32-2.5\Release\foo.o -LD:\Python25\libs -L D:\Python25\PCBuild -lpython25 -lmsvcr71 -o foo.pyd</pre>
<p>编译完毕，可以看到当前目录下多了：build目录、foo.c、foo.pyd。foo.pyd 即是编译好的二进制扩展。</p>
<pre>C:\&gt;python
ActivePython 2.5.0.0 (ActiveState Software Inc.) based on
Python 2.5 (r25:51908, Mar 9 2007, 17:40:28) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; import foo
&lt;module 'foo' from 'foo.pyd'&gt;
&gt;&gt;&gt; foo.Foo("smallfish")
foo names: smallfish</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/53">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/53#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/53&title=Win Python Pyrex 扩展">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/53/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Query Profile 简单使用</title>
		<link>http://chenxiaoyu.org/blog/archives/25</link>
		<comments>http://chenxiaoyu.org/blog/archives/25#comments</comments>
		<pubDate>Mon, 16 Nov 2009 08:27:12 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://chenxiaoyu.org/blog/?p=25</guid>
		<description><![CDATA[MySQL Query Profile MySQL 5.0.37 以上开始支持 MySQL Query Profiler, 可以查询到此 SQL 会执行多少时间, 并看出 CPU/Memory 使用量, 执行过程中 System lock, Table lock 花多少时间等等.
详细可以参见官方文档：Using the New MySQL Query Profiler
启动
mysql&#62; set profiling=1;
Query OK, 0 rows affected (0.00 sec)
测试查询
mysql&#62; select count(*) from client where broker_id=2;
+----------+
&#124; count(*) &#124;
+----------+
&#124;      200 &#124;
+----------+
1 row in set (0.00 sec)
查看profiles
mysql&#62; show [...]]]></description>
			<content:encoded><![CDATA[<p>MySQL Query Profile MySQL 5.0.37 以上开始支持 MySQL Query Profiler, 可以查询到此 SQL 会执行多少时间, 并看出 CPU/Memory 使用量, 执行过程中 System lock, Table lock 花多少时间等等.</p>
<p>详细可以参见官方文档：<a href="http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html" target="_blank">Using the New MySQL Query Profiler</a></p>
<p>启动</p>
<pre>mysql&gt; set profiling=1;
Query OK, 0 rows affected (0.00 sec)</pre>
<p>测试查询</p>
<pre>mysql&gt; select count(*) from client where broker_id=2;
+----------+
| count(*) |
+----------+
|      200 |
+----------+
1 row in set (0.00 sec)</pre>
<p>查看profiles</p>
<pre>mysql&gt; show profiles;
+----------+------------+-----------------------------------------------+
| Query_ID | Duration   | Query                                         |
+----------+------------+-----------------------------------------------+
|        0 | 0.00007300 | set profiling=1                               |
|        1 | 0.00044700 | select count(*) from client where broker_id=2 |
+----------+------------+-----------------------------------------------+
2 rows in set (0.00 sec)</pre>
<p>查看单条profile</p>
<pre>mysql&gt; show profile for query 1;
+--------------------+------------+
| Status             | Duration   |
+--------------------+------------+
| (initialization)   | 0.00006300 |
| Opening tables     | 0.00001400 |
| System lock        | 0.00000600 |
| Table lock         | 0.00001000 |
| init               | 0.00002200 |
| optimizing         | 0.00001100 |
| statistics         | 0.00009300 |
| preparing          | 0.00001700 |
| executing          | 0.00000700 |
| Sending data       | 0.00016800 |
| end                | 0.00000700 |
| query end          | 0.00000500 |
| freeing items      | 0.00001200 |
| closing tables     | 0.00000800 |
| logging slow query | 0.00000400 |
+--------------------+------------+
15 rows in set (0.00 sec)

mysql&gt; alter table t engine=myisam;
Query OK, 112050 rows affected (0.64 sec)
Records: 112050  Duplicates: 0  Warnings: 0

mysql&gt; show profiles;
+----------+------------+-----------------------------------------------+
| Query_ID | Duration   | Query                                         |
+----------+------------+-----------------------------------------------+
|        0 | 0.00007300 | set profiling=1                               |
|        1 | 0.00044700 | select count(*) from client where broker_id=2 |
|        2 | 0.00003400 | set profiling=0                               |
|        3 | 0.00007400 | set profiling=1                               |
|        4 | 0.63789700 | alter table t engine=myisam                   |
|        5 | 0.00004000 | set profiling=0                               |
+----------+------------+-----------------------------------------------+
6 rows in set (0.00 sec)

mysql&gt; show profile for query 4;
+----------------------+------------+
| Status               | Duration   |
+----------------------+------------+
| (initialization)     | 0.00002900 |
| checking permissions | 0.00000800 |
| init                 | 0.00004000 |
| Opening table        | 0.00009400 |
| System lock          | 0.00000500 |
| Table lock           | 0.00000700 |
| setup                | 0.00004200 |
| creating table       | 0.00195800 |
| After create         | 0.00010900 |
| copy to tmp table    | 0.52264500 |
| rename result table  | 0.11289400 |
| end                  | 0.00004600 |
| query end            | 0.00000700 |
| freeing items        | 0.00001300 |
+----------------------+------------+
14 rows in set (0.00 sec)</pre>
<p>查看cpu资源等信息</p>
<pre>mysql&gt; show profile cpu for query 4;
+----------------------+------------+------------+------------+
| Status               | Duration   | CPU_user   | CPU_system |
+----------------------+------------+------------+------------+
| (initialization)     | 0.00002900 | 0.00000000 | 0.00000000 |
| checking permissions | 0.00000800 | 0.00000000 | 0.00000000 |
| init                 | 0.00004000 | 0.00000000 | 0.00000000 |
| Opening table        | 0.00009400 | 0.00100000 | 0.00000000 |
| System lock          | 0.00000500 | 0.00000000 | 0.00000000 |
| Table lock           | 0.00000700 | 0.00000000 | 0.00000000 |
| setup                | 0.00004200 | 0.00000000 | 0.00000000 |
| creating table       | 0.00195800 | 0.00000000 | 0.00100000 |
| After create         | 0.00010900 | 0.00000000 | 0.00000000 |
| copy to tmp table    | 0.52264500 | 0.55591600 | 0.04199300 |
| rename result table  | 0.11289400 | 0.00199900 | 0.00000000 |
| end                  | 0.00004600 | 0.00000000 | 0.00000000 |
| query end            | 0.00000700 | 0.00000000 | 0.00000000 |
| freeing items        | 0.00001300 | 0.00000000 | 0.00000000 |
+----------------------+------------+------------+------------+
14 rows in set (0.00 sec)</pre>
<p>其他属性列表</p>
<p>* ALL &#8211; displays all information<br />
* BLOCK IO &#8211; displays counts for block input and output operations<br />
* CONTEXT SWITCHES &#8211; displays counts for voluntary and involuntary context switches<br />
* IPC &#8211; displays counts for messages sent and received<br />
* MEMORY &#8211; is not currently implemented<br />
* PAGE FAULTS &#8211; displays counts for major and minor page faults<br />
* SOURCE &#8211; displays the names of functions from the source code, together with the name and line number of the file in which the function occurs<br />
* SWAPS &#8211; displays swap counts</p>
<p>设定profiling保存size</p>
<pre>mysql&gt; show variables where variable_name='profiling_history_size'; # 默认15条</pre>
<p>关闭</p>
<pre>mysql&gt; set profiling=0;</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/25">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/25#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/25&title=MySQL Query Profile 简单使用">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/mysql" rel="tag">MySQL</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/25/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python MySQL 库安装笔记</title>
		<link>http://chenxiaoyu.org/blog/archives/23</link>
		<comments>http://chenxiaoyu.org/blog/archives/23#comments</comments>
		<pubDate>Tue, 10 Nov 2009 07:11:05 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://pythonchina.org/smallfish/?p=23</guid>
		<description><![CDATA[其实MySQL-python安装很简直，以前一直也没在意，今天发觉换了1.2.3新版本，ms蹦出很多问题来了。
做个记录，防止以后有问题无处可查。
一般步骤是：
1. 安装easy_install
shell > wget http://peak.telecommunity.com/dist/ez_setup.py
shell > python ez_setup.py
会自动根据本机的py版本选择对应的egg，安装完可以看到有/usr/bin/easy_install程序了
2. 安装MySQL-python
shell > easy_install MySQL-python
到这里安装算是完成了，不过接下来测试就郁闷了。
在import MySQLdb出现了两个错误：
a). ImportError: libmysqlclient_r.so.15: cannot open shared object file: No such file or directory
这个错误一般解决比较简单，把路径加入到LD_LIBRARY_PATH即可，不过偶的现象比较强，因为没装MySQL，哈哈
b). ImportError: /lib/tls/libc.so.6: version `GLIBC_2.4' not found
解决这个错误的办法是不用easy_install了，直接下载MySQL-python-1.2.2.tar.gz包，然后就是三步走：
shell > tar zxvf MySQL-python-1.2.2.tar.gz
shell > cd MySQL-python-1.2.2
shell > python setup.py install

© smallfish for smallfish logs, 2009. &#124;
Permalink &#124;
No comment &#124;
Add to
del.icio.us

Post tags: MySQL, Python







Feed [...]]]></description>
			<content:encoded><![CDATA[<p>其实MySQL-python安装很简直，以前一直也没在意，今天发觉换了1.2.3新版本，ms蹦出很多问题来了。<br />
做个记录，防止以后有问题无处可查。</p>
<p>一般步骤是：</p>
<p>1. 安装easy_install</p>
<pre lan="shell">shell > wget http://peak.telecommunity.com/dist/ez_setup.py
shell > python ez_setup.py</pre>
<p>会自动根据本机的py版本选择对应的egg，安装完可以看到有/usr/bin/easy_install程序了</p>
<p>2. 安装MySQL-python</p>
<pre lan="shell">shell > easy_install MySQL-python</pre>
<p>到这里安装算是完成了，不过接下来测试就郁闷了。</p>
<p>在import MySQLdb出现了两个错误：</p>
<pre lan="shell">a). ImportError: libmysqlclient_r.so.15: cannot open shared object file: No such file or directory</pre>
<p>这个错误一般解决比较简单，把路径加入到LD_LIBRARY_PATH即可，不过偶的现象比较强，因为没装MySQL，哈哈</p>
<pre lan="shell">b). ImportError: /lib/tls/libc.so.6: version `GLIBC_2.4' not found</pre>
<p>解决这个错误的办法是不用easy_install了，直接下载MySQL-python-1.2.2.tar.gz包，然后就是三步走：</p>
<pre lan="shell">shell > tar zxvf MySQL-python-1.2.2.tar.gz
shell > cd MySQL-python-1.2.2
shell > python setup.py install</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/23">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/23#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/23&title=Python MySQL 库安装笔记">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/mysql" rel="tag">MySQL</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/23/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google App Engine 上试用 web.py 笔记</title>
		<link>http://chenxiaoyu.org/blog/archives/18</link>
		<comments>http://chenxiaoyu.org/blog/archives/18#comments</comments>
		<pubDate>Tue, 10 Nov 2009 07:02:36 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[GAE]]></category>

		<guid isPermaLink="false">http://pythonchina.org/smallfish/?p=18</guid>
		<description><![CDATA[看到有人在坛子里询问在GAE如何发布web.py有关问题，就尝试了一把。具体安装和使用过程如下，请对照自己本地路径相应修改：
1. 复制本地对应web.py目录到GAE对应应用目录
比如：D:\Python25\Lib\site-packages\web 到 e:\googleapp\pynotes
2. 写测试代码
app.yaml
application: pynotes
version: 1
runtime: python
api_version: 1

handlers:
-  url: /.*
   script: home.py
home.py
import web
render = web.template.render('templates/')
urls = (
    '/', 'index'
)
class index:
    def GET(self):
        web.header('Content-type', 'text/html')
        name = 'smallfish'
     [...]]]></description>
			<content:encoded><![CDATA[<p>看到有人在坛子里询问在GAE如何发布web.py有关问题，就尝试了一把。具体安装和使用过程如下，请对照自己本地路径相应修改：</p>
<p>1. 复制本地对应web.py目录到GAE对应应用目录</p>
<p>比如：D:\Python25\Lib\site-packages\web 到 e:\googleapp\pynotes</p>
<p>2. 写测试代码<br />
app.yaml</p>
<pre lan="yaml">application: pynotes
version: 1
runtime: python
api_version: 1

handlers:
-  url: /.*
   script: home.py</pre>
<p>home.py</p>
<pre lan="Python">import web
render = web.template.render('templates/')
urls = (
    '/', 'index'
)
class index:
    def GET(self):
        web.header('Content-type', 'text/html')
        name = 'smallfish'
        return render.index(name)
app = web.application(urls, globals())
main = app.cgirun() # 这行是发布到GAE的关键</pre>
<p>templates/index.html</p>
<pre lan="html">$def with (name)
<strong>hello, $name. test by web.py</strong></pre>
<p>3. 发布到GAE，测试</p>
<p>e:\googleapp>appcfg.py update pynotes/</p>
<p>到这里，一个简单web.py应用就完成了，然后刷新。GAE显示500 Error！</p>
<p>看后台GAE Log显示错误信息：”No module named templates“，去web.py官方溜达了一圈，发现在其cookbook里有一篇文档《<a href="http://webpy.org/cookbook/templates_on_gae" target="_blank">How to use templates on Google App Engine</a>》，里面说的很明白啦。</p>
<p>因为web.py的模板在GAE上文件系统会有所限制，所有本地得compile一下，具体命令是：<strong>python web/template.py &#8211;compile templates</strong> 最后一个参数是本地对应模板目录templates，如果有多个模板目录则一次运行一次。运行完会在templates会生成一个__init__.py，里面内容有兴趣可以看看，很眼熟的哦。</p>
<p>4. 再次发布到GAE，可以看到OK拉！</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/18">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/18#comments">4 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/18&title=Google App Engine 上试用 web.py 笔记">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/gae" rel="tag">GAE</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/18/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Python Mako Template 学习笔记</title>
		<link>http://chenxiaoyu.org/blog/archives/15</link>
		<comments>http://chenxiaoyu.org/blog/archives/15#comments</comments>
		<pubDate>Tue, 10 Nov 2009 06:53:31 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://pythonchina.org/smallfish/?p=15</guid>
		<description><![CDATA[Mako是什么？Moko是Python写的一个模板库，Python官网python.org用的就是它哦。其他废话也就不累赘了，直接来点代码，方便阅读与了解把。
(Mako官网地址：http://www.makotemplates.org/ ，可以下载安装包，推荐使用easy_install安装)
from mako.template import Template
mytemplate = Template("hello world!")
print mytemplate.render()
mytemplate = Template("hello, ${name}!")
print mytemplate.render(name="jack")
代码可以参考官方doc部分
mytemplate = Template(filename='/docs/mytmpl.txt')
print mytemplate.render()
还可以从设置模板为文件，设置filename属性
mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules')
print mytemplate.render()
文件还可以缓存到某个目录下，下面的/docs/mytmpl.txt会产生一个py：/tmp/mako_modules/docs/mytmpl.txt.py
from mako.lookup import TemplateLookup
mylookup = TemplateLookup(directories=['/docs'])
mytemplate = Template("""&#60;%include file="header.txt"/&#62; hello world!""", lookup=mylookup)
查找模板，方便统一模板路径使用。
mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules')
def serve_template(templatename, **kwargs):
mytemplate = mylookup.get_template(templatename)
print mytemplate.render(**kwargs)
改良了上面的查找方式

mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8',
              [...]]]></description>
			<content:encoded><![CDATA[<p>Mako是什么？Moko是Python写的一个模板库，Python官网<a href="http://python.org/" target="_blank">python.org</a>用的就是它哦。其他废话也就不累赘了，直接来点代码，方便阅读与了解把。</p>
<p>(Mako官网地址：<a href="http://www.makotemplates.org/" target="_blank">http://www.makotemplates.org/</a> ，可以下载安装包，推荐使用easy_install安装)</p>
<pre lan="Python">from mako.template import Template
mytemplate = Template("hello world!")
print mytemplate.render()
mytemplate = Template("hello, ${name}!")
print mytemplate.render(name="jack")</pre>
<p>代码可以参考官方doc部分</p>
<pre lan="Python">mytemplate = Template(filename='/docs/mytmpl.txt')
print mytemplate.render()</pre>
<p>还可以从设置模板为文件，设置filename属性</p>
<pre lan="Python">mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules')
print mytemplate.render()</pre>
<p>文件还可以缓存到某个目录下，下面的/docs/mytmpl.txt会产生一个py：/tmp/mako_modules/docs/mytmpl.txt.py</p>
<pre lan="Python">from mako.lookup import TemplateLookup
mylookup = TemplateLookup(directories=['/docs'])
mytemplate = Template("""&lt;%include file="header.txt"/&gt; hello world!""", lookup=mylookup)</pre>
<p>查找模板，方便统一模板路径使用。</p>
<pre lan="Python">mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules')
def serve_template(templatename, **kwargs):
mytemplate = mylookup.get_template(templatename)
print mytemplate.render(**kwargs)</pre>
<p>改良了上面的查找方式</p>
<pre lan="Python">
mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8',
                                       encoding_errors='replace')
mytemplate = mylookup.get_template("foo.txt")
print mytemplate.render()</pre>
<p>设置输出编码，以及编码错误时候处理方式</p>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/15">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/15#comments">2 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/15&title=Python Mako Template 学习笔记">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/15/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python MySQLdb 查询返回字典结构</title>
		<link>http://chenxiaoyu.org/blog/archives/6</link>
		<comments>http://chenxiaoyu.org/blog/archives/6#comments</comments>
		<pubDate>Tue, 10 Nov 2009 06:20:55 +0000</pubDate>
		<dc:creator>smallfish</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://pythonchina.org/smallfish/?p=6</guid>
		<description><![CDATA[MySQLdb默认查询结果都是返回tuple，输出时候不是很方便，必须按照0，1这样读取，无意中在网上找到简单的修改方法，就是传递一个cursors.DictCursor就行。
默认程序：
import MySQLdb
db = MySQLdb.connect(host = 'localhost', user = 'root', passwd = '123456', db = 'test')
cursor = db.cursor()
cursor.execute('select * from user')
rs = cursor.fetchall()
print rs
# 返回类似如下
# ((1000L, 0L), (2000L, 0L), (3000L, 0L))
修改后：
import MySQLdb
import MySQLdb.cursors
db = MySQLdb.connect(host = 'localhost', user = 'root', passwd = '123456', db = 'test',
           [...]]]></description>
			<content:encoded><![CDATA[<p>MySQLdb默认查询结果都是返回tuple，输出时候不是很方便，必须按照0，1这样读取，无意中在网上找到简单的修改方法，就是传递一个cursors.DictCursor就行。</p>
<p>默认程序：</p>
<pre lan="Python">import MySQLdb
db = MySQLdb.connect(host = 'localhost', user = 'root', passwd = '123456', db = 'test')
cursor = db.cursor()
cursor.execute('select * from user')
rs = cursor.fetchall()
print rs
# 返回类似如下
# ((1000L, 0L), (2000L, 0L), (3000L, 0L))</pre>
<p>修改后：</p>
<pre lan="Python">import MySQLdb
import MySQLdb.cursors
db = MySQLdb.connect(host = 'localhost', user = 'root', passwd = '123456', db = 'test',
                     cursorclass = MySQLdb.cursors.DictCursor)
cursor = db.cursor()
cursor.execute('select * from user')
rs = cursor.fetchall()
print rs
# 返回类似如下
# ({'age': 0L, 'num': 1000L}, {'age': 0L, 'num': 2000L}, {'age': 0L, 'num': 3000L})</pre>
<p>或者也可以用下面替换connect和cursor部分</p>
<pre lan="Python">db = MySQLdb.connect(host = 'localhost', user = 'root', passwd = '123456', db = 'test')
cursor = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)</pre>
<hr />
<p><small>© smallfish for <a href="http://chenxiaoyu.org">smallfish logs</a>, 2009. |
<a href="http://chenxiaoyu.org/blog/archives/6">Permalink</a> |
<a href="http://chenxiaoyu.org/blog/archives/6#comments">3 comments</a> |
Add to
<a href="http://del.icio.us/post?url=http://chenxiaoyu.org/blog/archives/6&title=Python MySQLdb 查询返回字典结构">del.icio.us</a>
<br/>
Post tags: <a href="http://chenxiaoyu.org/blog/archives/tag/mysql" rel="tag">MySQL</a>, <a href="http://chenxiaoyu.org/blog/archives/tag/python" rel="tag">Python</a><br/>
</small></p>
<p>
<script type="text/javascript"><!--
google_ad_client = "pub-8914011260472945";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "7198645178";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://chenxiaoyu.org/blog/archives/6/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
