这是一种似乎合理的方法。首先,我继承了 couchdb.design.ViewDefinition。(为简洁起见,删除了评论和 pydocs。)
import couchdb.design
import inflection
DESIGN_NAME="version"
class CurrentVersion(couchdb.design.ViewDefinition):
def __init__(self):
map_fun = self.__class__.map
if hasattr(self.__class__, "reduce"):
reduce_fun = self.__class__.reduce
else:
reduce_fun = None
super_args = (DESIGN_NAME,
inflection.underscore(self.__class__.__name__),
map_fun,
reduce_fun,
'python')
super(CurrentVersion, self).__init__(*super_args)
@staticmethod
def map(doc):
if 'version_key' in doc and 'created_ts' in doc:
yield (doc['version_key'], [doc['_id'], doc['created_ts']])
@staticmethod
def reduce(keys, values, rereduce):
max_index = 0
for index, value in enumerate(values):
if value[1] > values[max_index][1]:
max_index = index
return values[max_index]
现在,如果我想同步:
import couchdb.design
from couchview.version import CurrentVersion
db = get_couch_db() # omitted for brevity
couchdb.design.ViewDefinition.sync_many(db, [CurrentVersion()], remove_missing=True)
这种方法的好处是:
- 组织。所有设计/视图都作为位于单个包中的模块/类(分别)存在。
- 真实代码。我的文本编辑器将突出显示语法。我可以针对我的 map/reduce 函数编写单元测试。
ViewDefinition 子类也可用于查询。
current_version_view = couchview.version.CurrentVersion()
result = current_version_view(self.db, key=version_key)
它还没有准备好投入生产,但我认为这与将 map/reduce 函数存储在字符串文字中相比更近了一步。
编辑:我最终写了几篇关于这个主题的博客文章,因为我找不到任何其他的建议来源: