跳转到主要内容

另一个MongoDB文档映射器(ODM)

项目描述

https://travis-ci.org/zzzsochi/yadm.svg?branch=master https://coveralls.io/repos/github/zzzsochi/yadm/badge.svg?branch=master

这是一个小型且简单的ODM,用于与MongoDB一起使用。

需求

YADM仅支持MongoDB版本3.x。不支持MongoDB 2.x。

Python的最小版本为3.6。

快速入门

创建模型

from datetime import datetime

import pymongo

from yadm import Database
from yadm import Document, EmbeddedDocument
from yadm import fields
from yadm.serialize import to_mongo


class User(Document):
    __collection__ = 'users'

    name = fields.StringField()
    email = fields.EmailField()


class PostLogItem(EmbeddedDocument):
    op = fields.StringField(choices=['created', 'comment_added'])
    at = fields.DatetimeField()
    data = fields.MongoMapField()


class Post(Document):
    __collection__ = 'posts'

    user = fields.ReferenceField(User)
    created_at = fields.DatetimeField(auto_now=True)
    title = fields.StringField()
    body = fields.StringField()
    log = fields.ListField(fields.EmbeddedDocumentField(PostLogItem))


class Comment(Document):
    __collection__ = 'comments'

    user = fields.ReferenceField(User)
    created_at = fields.DatetimeField(auto_now=True)
    post = fields.ReferenceField(Post)
    text = fields.StringField()

所有文档都从Document类创建。您可以使用多重继承。

__collection__魔术属性为模型的文档设置集合名称。

连接到数据库

client = pymongo.MongoClient('mongodb://localhost:27017')
db = Database(client, 'blog')

Database对象是关于pymongomotor Database的包装器。

创建文档

用户

user = User(name='Bill', email='bill@galactic.hero')
db.insert_one(user)

只需将文档插入数据库。

帖子

post = Post()
post.user = user
post.title = 'Small post'
post.body = 'Bla-bla-bla...'
post.log = [PostLogItem(op='created', at=datetime.utcnow())]
db.insert_one(post)

您可以根据上述方式填充文档。

评论帖子

comment = Comment()
comment.user = user
comment.post = post
comment.text = "RE: Bla-bla-bla..."
db.insert_one(comment)
db.update_one(post, push={
    'log': to_mongo(PostLogItem(op='comment_added',
                                at=comment.created_at,
                                data={
                                  'comment': comment.id,
                                  'user': comment.user.id,
                                }))
})

我们向帖子的日志中添加日志项。这是一个非常有用的案例。

查询

find

qs = db(Post).find({'title': {'$regex': '^S'}})
assert qs.count() > 0
  1. db(Post)创建QuerySet对象;

  2. find方法获取原始查询并返回具有更新条件的新的QuerySet对象;

  3. count方法对数据库进行查询并返回值。

for post in qs:
    assert post.title.startswith('S')

__iter__方法执行find-查询并返回文档生成器。

find_one

获取第一个找到的文档。

post = db(Post).find_one({'user': user.id})

get_document

从主键获取id的文档。

user = db.get_document(User, user.id)

参考文献

user = post.user

通过引用获取属性会使查询引用集合。警告:N+1问题!我们在QuerySet对象中有一个缓存,并且对于每个queryset只获取一次引用文档。

查找

comments = db(Comment).find({'post': post.id}).sort(('created_at', 1))
for comment in comments.lookup('user'):
    print(comment.user.name, comment.text)

此代码使用$lookup语句创建聚合查询以解决引用。

聚合

agg = (db.aggregate(Comment)
       .match(user=user.id)
       .group(_id='post', count={'$sum': 1})
       .sort(count=-1))

for item in agg:
    print(item)

或传统的MongoDB语法

agg = db.aggregate(Comment, pipeline=[
    {'match': {'user': user.id}},
    {'group': {'_id': 'post', 'count': {'$sum': 1}}},
    {'sort': {'count': -1}},
])

变更

2.0.9 (2023-08-23)

  • 为QuerySet和Aggregation添加了comment方法,以指定MongoDB的注释功能。

2.0.8 (2021-09-23)

  • 异步IO支持测试。

2.0.7 (2021-04-21)

  • 一些错误修复。

2.0.5 (2019-02-25)

  • 添加Aggregation.hint方法。

2.0.4 (2019-02-20)

  • 添加Database.estimated_document_count方法,用于快速计数集合中的文档。

2.0.1 (2018-11-04)

  • 为查询添加QuerySet.hint,以指定查询的索引。

2.0.0 (2018-10-25)

  • 一个重大重写文档逻辑
    • Document.__raw__现在只包含来自pymongo的数据,不包含任何AttributeNotSetNotLoaded

    • Document.__changed__已删除:所有更改都反映在Document.__cache__中;

    • Document.__not_loaded__是未通过投影加载的字段的frozenset;

    • Document.__new_document__标志对于直接在您的代码中创建的文档对象为True

    • Document.__log__是一个类似列表的容器,包含文档变更日志(目前为不稳定API);

    • Document.__data__已删除作为弃用;

    • 现在不允许将字段设置为类;

    • 默认值不是懒加载,并且与文档实例一起创建;

  • 针对pymongo(3.7)和motor(2.0)的最低版本更新
    • 添加Database.bulk_write

    • 添加Database.insert_oneDatabase.insert_manyDatabase.delete_one

    • 弃用Database.insertDatabase.remove

    • 删除Database.bulk(没有弃用期限,抱歉);

    • 添加QuerySet.count_documents

    • 添加QuerySet.update_oneQuerySet.update_many

    • 添加QuerySet.delete_oneQuerySet.delete_many

    • 添加QuerySet.find_one_and_updateQuerySet.find_one_and_replaceQuerySet.find_one_and_delete

    • 弃用QuerySet.count

    • 弃用QuerySet.updateQuerySet.removeQuerySet.find_and_modify

    • 删除已弃用的QuerySet.with_id

  • 构建查找的简单接口:QuerySet.lookup

  • MoneyField中删除bcc参数;

  • 添加Decimal128Field

1.5.0 (2017-12-31)

  • 实验性的asyncio支持;

  • 为引用列表添加ReferencesListField

1.4.15 (2017-12-27)

  • projection参数添加到Database.get_documentDatabase.reload

  • 添加Document.__default_projection__属性。

1.4.14 (2017-11-06)

  • 为保存enum.Enum添加EnumField

  • 为基于enum.Enum的简单状态机添加EnumStateField

1.4.13 (2017-10-31)

  • 为设置游标的批量大小添加QuerySet.batch_size方法;

  • 一些小修复。

1.4.10 (2017-07-07)

  • ReferenceField.from_mongo在默认情况下通过主文档尝试获取文档

    如果未找到。

1.4.9 (2017-07-06)

  • 添加QuerySet.read_primary方法,以便于简单的设置read_preference.Primary

1.4.4 (2017-05-17)

  • 添加TimedeltaField用于存储持续时间;

  • 添加SimpleEmbeddedDocumentField,以简单创建嵌入式文档。

class Doc(Document):
    embedded = SimpleEmbeddedDocumentField({
        'i': IntegerField(),
        's': StringField(),
    })

1.4.3 (2017-05-14)

  • 添加StaticField用于静态数据。

1.4.2 (2017-04-09)

  • 写入操作中添加额外的参数(如write_concern);

  • create_fake默认将文档以“majority”写入关注保存。

1.4.0 (2017-04-05)

  • 取消对pymongo 2的支持;

  • 数据库和集合的附加选项;

  • 添加Database.get_document

  • 添加TypedEmbeddedDocumentField

  • Database.update_onereload参数必须是关键字(可能存在向后不兼容的问题)。

    (可能存在向后不兼容)。

1.3.1 (2017-02-21)

  • 更改Money的原始数据;

1.3.0 (2017-02-19)

  • 将货币支持添加到Money
    • 完全重写Money类型。现在它不再是Decimal的子类;

    • 添加货币存储:yadm.fields.money.currency.DEFAULT_CURRENCY_STORAGE

1.2.1 (2017-01-19)

  • 添加QuerySet.find_in,用于具有指定顺序的$in查询;

1.2.0 (2016-12-27)

  • 取消对MongoDB 2.X的支持;

  • 用于更新和删除结果的对象;

  • 使用Faker代替fake-factory。

1.1.4 (2016-08-20)

  • Bulk添加一些功能
    • Bulk.update_one(document, **kw):用于在批量中添加更新单个文档的方法;

    • Bulk.find(query).update(**kw):通过查询更新多个文档;

    • Bulk.find(query).upsert().update(**kw):更新文档;

    • Bulk.find(query).remove(**kw):删除文档;

1.1.3 (2016-07-23)

  • 添加QuerySet.ids方法,用于从查询集中获取仅文档ID;

  • 添加Money.total_cents方法和Money.from_cents类方法;

1.1 (2016-04-26)

  • 在查询集级别添加缓存并用于ReferenceField

  • 添加Mongo聚合框架支持;

  • 添加read_preference设置;

  • QuerySet.find_one添加exc参数,如果未找到则引发异常;

  • QuerySet.remove添加multi参数;

  • 弃用QuerySet.with_id

  • 重构。

1.0 (2015-11-14)

  • 更改文档结构。不再有恶心的BaseDocument.__data__属性
    • BaseDocument.__raw__:来自mongo的原始数据;

    • BaseDocument.__cache__:缓存的对象,经过字段转换;

    • BaseDocument.__changed__:更改的对象。

  • 自定义字段的API更改
    • 不再需要为每个字段创建字段描述符;

    • prepare_value仅在setattr时调用;

    • to_mongo仅在将对象保存到mongo时调用;

    • from_mongo仅在从BaseDocument.__raw__加载值时调用;

    • 删除Field.default属性。使用Field.get_default方法;

    • 添加Field.get_if_not_loadedField.get_if_attribute_not_set方法;

    • 默认情况下,如果字段未从投影中加载,则引发NotLoadedError

  • ReferenceField的更改
    • 如果链接损坏,则引发BrokenReference

    • 如果文档未保存到数据库,则引发NotBindingToDatabase

  • smart_null关键字用于Field

  • 文档中的字段必须是实例(不是类!);

  • 删除ArrayContainerArrayContainerField

  • 删除旧的MapIntKeysFieldMapObjectIdKeysField。使用新的MapCustomKeysField

  • 添加Database.update_one方法,用于运行指定文档的简单更新查询;

  • 添加QuerySet.distinct

  • serialize.from_mongo 现在接受具有必须标记为未加载的字段名、parentnamenot_loaded 序列;

  • serialize.to_mongo 不调用 FieldDescriptor.__set__

  • 伪造者!生成测试对象的子系统;

  • 测试现在使用 pytest;

  • 还有更多,更多...

项目详情


发布历史 发布通知 | RSS 源

下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分发

yadm-2.0.9.tar.gz (72.1 kB 查看哈希)

上传时间

构建分发

yadm-2.0.9-py3-none-any.whl (59.7 kB 查看哈希)

上传时间 Python 3

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面