本文来自依云's Blog,转载请注明。
不知道怎么搞的,新版 MongoDB 自带的 mongo shell 现在不支持 readline,而且使用一个极简到工作不正常的 linenoise。编译时加上 readline 也没用。虽然内建了简单的历史记录和补全,可是历史记录不能搜索,补全只能像 Vim 命令行默认的那样一个一个切换不能像 bash/zsh 那样全部列出来。这些还不是最令人郁闷的。最让我受不了的问题和十年前的 DOS 版 WPS 里遇到的差不多——当年的 WPS 里删汉字一次只删一半,现在的 mongo shell 里删汉字一次只删三分之一!而且光标定位是错的,按字节算的!
于是乎拿 Python 写了一个 shell。不愧是 Python,内置的东西真不错,不到100行就写好了。不过用到了自己另外的库函数,另外用到了自己的 colorless 程序来高亮显示查询结果。如果不想要 pygments 这个依赖的话,可以用 less 程序代替。以下贴个无高亮版的,高亮版的见 github。
#!/usr/bin/env python3 # vim:fileencoding=utf-8 import sys import os from pprint import pprint import subprocess from pymongo import Connection import pymongo.cursor # 这个模块位于 github 上的 winterpy 仓库的 pylib/cli.py from cli import repl import locale locale.setlocale(locale.LC_ALL, '') del locale host = 'localhost' port = 27017 db = 'test' def displayfunc(value): if isinstance(value, pymongo.cursor.Cursor): p = subprocess.Popen(['less', '-RFX'], stdin=subprocess.PIPE, universal_newlines=True) pprint(list(value), stream=p.stdin) p.stdin.close() p.wait() else: pprint(value) def main(): global db conn = Connection(host=host, port=port) db = conn[db] v = globals().copy() v.update(locals()) del v['repl'], v['argv'], v['main'], v['v'], v['host'], v['port'] del v['displayfunc'], v['subprocess'] del v['__name__'], v['__cached__'], v['__doc__'], v['__file__'], v['__package__'] sys.displayhook = displayfunc repl( v, os.path.expanduser('~/.mongo_history'), banner = 'Python MongoDB console', ) if __name__ == '__main__': argv = sys.argv if len(argv) == 2: if '/' in argv[1]: host, db = argv[1].split('/', 1) if ':' in host: host, port = host.split(':', 1) elif len(argv) == 1: pass else: sys.exit('argument error') main()
Nov 30, 2011 08:03:09 AM
MongoDB? 它跟 MySQL 相比如何,好处有哪些?
Nov 30, 2011 01:30:40 PM
schemaless 是它最大的好处,其它的还有 capped collection 用作日志很适合,最后,查询语言(对程序员来说)比较自然,看一遍就会了。
Mar 04, 2012 08:29:55 AM
用 rlwrap 包装一下怎么样?
Mar 04, 2012 01:12:17 PM
buggy!
Nov 23, 2013 01:32:32 AM
from cli import repl
这是哪个包里的?..找不到啊= =
Nov 23, 2013 01:40:01 AM
我错了。。原来是你自己写的。。
Nov 23, 2013 11:50:19 AM
嗯嗯。看来把 import 分成标准库、第三方库和自己的东西还是很有用的呀 =w=