项目碰到要使用mongodb的场景,以前只听过这一强大的文档数据库,但一直没有真正使用过,参考一下项目中已有的使用代码,是通过import mongoengine这一模块实现python服务对db中collection的增删查改。

mongoengine的项目网站http://mongoengine.org 中介绍到:

MongoEngine is a Document-Object Mapper (think ORM, but for document databases) for working with MongoDB from Python.

大意是,MongoEngine是一个针对在Python中方便使用MongoDB的文档对象的映射器(类似ORM(Object Relational Mapping),但是是针对文档数据库)

参考已有的代码时发现,代码通过定义一个继承mongoengine.Document(定义于mongoengine/document.py文件中)的Python类和db中的collection建立了映射关系,通过对类的操作即可实现对db中对应collection的操作。

例如UserInfo的类定义如下:

class UserInfo(Document):
"""
用户数据对象
"""
meta = {
'db_alias': 'user',
'indexes': [
'user_id',
'user_type'
]
} user_type = IntField(default=USER_COOP)
user_id = StringField(default='', max_length=64)
nickname = StringField(detault='', max_length=16) ctime = DateTimeField(default=datetime.utcnow)
mtime = DateTimeField(default=datetime.utcnow)

其中meta用于定义类的一些元信息,如db_alias代表要访问的mongodb中具体的db名称,indexes则定义索引(用处?)。

然而其中并没有发现指定访问的collection名称的代码,估计是根据某种特殊规则从类的信息推断生成出来的,这引起了我的好奇,想要探究一番其生成原理。

通过远程登录上mongodb,使用"show collections"查看user db中的collection列表,发现了名叫user_info的collection,实际测试也确认UserInfo类查询的具体数据来源于其中

通过进一步参考官方文档,发现meta中可以通过指定"collection"的key-value对人工指明UserInfo类绑定的collection,然而上述代码中并没有用到这一机制。官方文档中说到mongodb默认通过将Document子类的名称转换为小写来作为db中对应collection的名称:

By default, the MongoDB collection used to store documents created using a Document subclass will be the name of the subclass converted to lowercase. A different collection may be specified by providing collection to the meta dictionary in the class definition.

然而这样的话UserInfo对应的名称应该是userinfo,而不是user_info才对。

使用开源软件的优势果断凸显出来了,拜读源码,研究个清楚。

查找源码发现mongoengine中的Document类中定义有类成员my_metaclass和__metaclass,其类型均为TopLevelDocumentMetaclass,collection名称根据UserInfo自动生成的逻辑就在这里面。

# The __metaclass__ attribute is removed by 2to3 when running with Python3

# my_metaclass is defined so that metaclass can be queried in Python 2 & 3

my_metaclass = TopLevelDocumentMetaclass
__metaclass__ = TopLevelDocumentMetaclass TopLevelDocumentMetaclass的定义在mongoengine/base/metaclasses.py中: class TopLevelDocumentMetaclass(DocumentMetaclass): """Metaclass for top-level documents (i.e. documents that have their own collection in the database. """ ...

针对collection名称自动生成的逻辑就在其__new__函数之中,其会在meta中没有collection字段时,根据以下代码片段生成默认collection名称:

        # Set default collection name

        if 'collection' not in meta:

           meta['collection'] = ''.join('_%s' % c if c.isupper() else c

                                         for c in name).strip('_').lower()

看到这里就一切了然了,将name中的所有大写字母转换为小写+'_'的形式(UserInfo->_user_info),而后strip两边的'_'(_user_info->user_info)

mongoengine中collection名称自动生成机制浅探的更多相关文章

  1. 痞子衡嵌入式:MCUXpresso IDE下工程链接文件配置管理与自动生成机制

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下工程链接文件配置管理与自动生成机制. 痞子衡在 2018 年初写过一个专题 <嵌入式开发文件系列&g ...

  2. mysql中timestamp的自动生成与更新

    转自:mysql中timestamp的自动生成与更新 MYSQL中TIMESTAMP类型可以设定默认值,就像其他类型一样.1.自动UPDATE 和INSERT 到当前的时间:表:----------- ...

  3. Markdown 中的目录自动生成功能 TOC

    目录 Markdown 中的目录自动生成功能 TOC 1. 标题一 1.1 标题二 1.标题二 2. 标题一 2.1 标题二 2.2 标题二 Markdown 中的目录自动生成功能 TOC 1. 标题 ...

  4. 【转】Intellij IDEA 14中使用MyBatis-generator 自动生成MyBatis代码

    Intellij IDEA 14 作为Java IDE 神器,接触后发现,非常好用,对它爱不释手,打算离开eclipse和myeclipse,投入Intellij IDEA的怀抱. 然而在使用的过程中 ...

  5. Intellij IDEA 14中使用MyBatis-generator 自动生成MyBatis代码

    一:项目建立好及其基本的测试好 二:在maven项目的pom.xml 添加mybatis-generator-maven-plugin 插件 <build> <finalName&g ...

  6. IDEA 中使用MyBatis-generator 自动生成MyBatis代码

    0.在Intellij IDEA创建maven项目 1. 在maven项目的pom.xml 添加mybatis-generator-maven-plugin 插件 <build> < ...

  7. asp.net mvc5中使用Swagger 自动生成WebApi文档笔记

    Swagger可以自动生成Api说明文档,并内置在线测试,通过NSwagStudio还可以自动生成Api客户端调用代码,以下为具体实现步骤 1.写一个简单的WebApi并加上注释 public cla ...

  8. idea中mybatis generator自动生成代码配置 数据库是sqlserver

    好长时间没有写博客了,最近公司要用java语言,开始学习java,属于初学者,今天主要记录一下mybatis generator自动生成代码,首先在如下图的目录中新建两个文件,如下图 generato ...

  9. mongoengine中queryset触发网络访问机制剖析

    背景 最近新上线的一个服务,偶尔会有超时告警,其主要逻辑仅仅只是简单的读/写mongodb,而且服务上线初期,流量并不大,因而理论上来说,每次请求都应该很快才对,事实上分析日志也证实90%以上的请求都 ...

随机推荐

  1. boost::intrusive_ptr原理介绍

    boost::intrusive_ptr一种“侵入式”的引用计数指针,它实际并不提供引用计数功能,而是要求被存储的对象自己实现引用计数功能,并提供intrusive_ptr_add_ref和intru ...

  2. 使用websploit在局域网全自动渗透

    原理为 websploit调用dnsdpoof进行dns欺骗配合神器metasploit的web_autopwn模块进行渗透:特点:过程基本全自动. 终端输入websploit打开websploit: ...

  3. JAVA中高访问量高并发的问题怎么解决?

    尽量使用缓存,包括用户缓存,信息缓存等,多花点内存来做缓存,可以大量减少与数据库的交互,提高性能. 用jprofiler等工具找出性能瓶颈,减少额外的开销. 优化数据库查询语句,减少直接使用hiber ...

  4. import(导入)过期的磁带 -----先留个引子,后期更改补充

    在某些情况下,客户需要恢复已经过期的磁带上的数据, 如果磁带没有被重新使用,数据没有被覆盖掉,可以使用 netbackup 的 import 方法将过期的磁带上的数据 import 到 netback ...

  5. Linux CentOS6系统安装最新版本Node.js环境及相关文件配置

    Node.js,当前应用非常广泛的Javascript运行环境,采用C++编写的,目前应用较多的用于WEB应用中,执行效率还是非常高的,虽然老左不从业程序的开发,但是有些时候在玩VPS的时候还是会遇到 ...

  6. Windows 2008 Scheduled tasks result codes

    0 or 0x0: The operation completed successfully. 1 or 0x1: Incorrect function called or unknown funct ...

  7. python-常用模块之os、sys

    一.os os模块包含普遍的操作系统功能: os.pardir #获取当前目录的父目录字符串名:('..') os.makedirs('dirname1/dirname2') #可生成多层递归目录 o ...

  8. 设计模式——Spirng_Bean工厂

    前言:对于简单工厂和抽象工厂都有自己的优点和缺点, 比如简单工厂,如果你需要实现的类过多,你最后会出现工厂泛滥的情况,没有有效的控制代码的可重复性.http://www.cnblogs.com/xia ...

  9. IBAction作用相当于void,NSLog(@"被调用的方法名是%s",__func__);

    IBAction作用相当于void,NSLog(@"被调用的方法名是%s",__func__);

  10. iOS应用软件沙盒sandbox相关知识(整理)

    1.iOS沙盒机制原理 iOS应用程序只能在该程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等. ...