跳转到主要内容

小型自然对象/mongodb驱动程序

项目描述

micromongo是围绕pymongo的一个小层,允许您创建简单的ORM样式类,可以执行验证、允许对文档进行点访问、自动包装查询集结果,并提供预/后保存钩子。

它针对微框架进行了设计,但与特定应用和框架无关。它的目的是简化pymongo的使用,并提供常用语法的工具,而不是使pymongo或mongodb从您的数据结构中消失。

您可以在micromongo的github上打开问题或发送pull请求。

micromongo在简化的名义下做出了一些设计决策,这些决策可能不适合您

  • micromongo维护单个全局连接,因此您不能有连接到多个mongodb服务器的模型

  • 有一些模型名称和文档属性名称在micromongo模型中不起作用;这些将在完整文档中介绍

  • 每个集合只能有一个模型

入门指南

要开始使用micromongo,只需导入它即可

>>> from micromongo import connect, Model
>>> c = connect()

connect 函数接受与 pymongo 的 Connection 对象 相同的参数,并且行为几乎相同,唯一的区别在于它会尝试自动返回用适当的 Model 类包装的查询结果。通过这个调用创建的连接对象将被缓存,并由各种 ORM 风格的设施使用,如 Model.save()Model.proxy 等。如果您想要一个干净的标准 Connection 对象,您可以轻松获取一个。

>>> from micromongo import clean_connection
>>> clean = clean_connection()

请注意,clean_connection 不接受任何参数,并且总是返回与当前 micromongo 连接相同设置的干净 Connection 类。

使用这些连接对象,您可以创建数据库或执行您会使用正常 pymongo 对象所做的任何操作。

>>> db = c.test_db
>>> collection = db.test_collection
>>> collection.save({"docid": 1, "fail": False})
>>> collection.find_one()
{u'_id': ObjectId('...'), u'fail': False, u'docid': 1}

您还可以以声明性风格为特定集合声明您自己的 Model。

>>> class TestModel(Model):
        collection = 'test_db.test_collection'

>>> collection.find_one()
<TestModel: {u'_id': ObjectId('...'), u'fail': False, u'docid': 1}>

这些类相较于字典具有许多额外功能,使得它们更加方便使用。文档键都可以作为属性访问。

>>> t = collection.find_one()
>>> t.fail
False
>>> t.docid
1

文档也可以轻松持久化到数据库。

>>> t.docid = 17
>>> t.save()
>>> clean.test_db.test_collection.find_one()
{u'_id': ObjectId('...'), u'fail': False, u'docid': 17}

定义模型

上面,将 collection 属性分配给了我们的 Foo 模型。这是一个快捷方式;如果单独分配了 databasecollection,模型可以自己推断完整的集合名称。如果集合和数据库都不存在,micromongo 会尝试根据您的模型类和模块名称来推断。例如,blog.Post 将变为 blog.post,或 stream.StreamEntry 将变为 stream.stream_entry。显式比隐式更好,并且建议您手动设置集合。

除了打包和提取数据库结果外,模型还可以定义一个 spec 文档,该文档可以定义默认值并在保存模型之前执行验证。以下是一个简单的博客帖子模型示例:

>>> from micromongo.spec import *
>>> class Post(Model):
        collection = 'test_db.blog_posts'
        spec = dict(
            author=Field(required=True, default='jmoiron', type=basestring),
            title=Field(required=False, default='', type=basestring),
            published=Field(required=True, default=False, type=[True, False]),
            body=Field(type=unicode),
            timestamp=Field(),
        )

>>> p = Post.new()
>>> p
<Post: {'title': u'', 'author': u'jmoiron', 'published': False}>

这里有几个要点。具有默认值的字段将初始化为该默认值,无论它们是否是必需的。如果必需的字段没有默认值,它将初始化为 None

字段可以接受一个 type 参数,该参数可以是接受一个值并返回 True 或 False 的可调用对象,一个或多个基类型,或一个或多个值。如果提供了一个或多个类型,则使用 isinstance 来测试值是否是正确的类型。如果提供了一个或多个值,字段充当枚举类型,检查值是否在其值集中。如果没有给出类型,除非它是必需的且不存在,否则验证总是通过字段。

如果 p 中的字段被赋予了一个无效的类型,则会引发 ValueError

>>> p.title = 10
>>> p.save()
Traceback (most recent call last):
  ...
ValueError: Keys did not match spec: ['title']
>>> del p.author
>>> p.save()
Traceback (most recent call last):
  ...
ValueError: Missing fields: ['author'], Invalid fields: ['title']
>>> p.title = 'My first blogpost'
>>> p.author = 'jmoiron'
>>> p.published = True
>>> p.body = u"This is my first blog post..  I'm so excited!"
>>> p.save()

Model.find

为了方便和遵循 DRY 原则,Model.find 是一个类方法,它将使用 micromongo 的游标向正确的集合发出 find 操作。此方法的行为与 pymongo 的 Collection.find 完全相同。

micromongo 的略微修改的 Cursor 类还使所有游标(find 和返回游标的任何链式操作)都可用 django 启发的 order_by 方法。您可以传递一个或多个字段名称,可选地带有前缀“-”,以升序或降序排序。

这些更改允许您在不导入的情况下使用 pymongo 的大部分功能,并让您避免重复指定数据位置。

字段子类化

鼓励您创建自己的字段,以满足您的需求。字段子类具有一个钩子函数 pre_validate,它接受传入的值并可以按照自己的意愿进行转换。请注意,这仅适用于实际存在的字段;因此,要在 DateTimeField 上实现类似于 auto_now_add 的功能,您需要将其设置为必填项,并在其 pre_validate 中将 None 转换为 datetime.datetime.now()

支持