11
28
2011
7

弄了个支持 readline 的 MongoDB shell

本文来自依云'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()
Category: python | Tags: python MongoDB linenoise readline | Read Count: 7386
Avatar_small
Jacky Liu 说:
Nov 30, 2011 08:03:09 AM

MongoDB? 它跟 MySQL 相比如何,好处有哪些?

Avatar_small
依云 说:
Nov 30, 2011 01:30:40 PM

schemaless 是它最大的好处,其它的还有 capped collection 用作日志很适合,最后,查询语言(对程序员来说)比较自然,看一遍就会了。

MaskRay 说:
Mar 04, 2012 08:29:55 AM

用 rlwrap 包装一下怎么样?

ppwwyyxx 说:
Nov 23, 2013 01:32:32 AM

from cli import repl
这是哪个包里的?..找不到啊= =

ppwwyyxx 说:
Nov 23, 2013 01:40:01 AM

我错了。。原来是你自己写的。。

Avatar_small
依云 说:
Nov 23, 2013 11:50:19 AM

嗯嗯。看来把 import 分成标准库、第三方库和自己的东西还是很有用的呀 =w=


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com