项目碰到要使用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. delegate 和 event

    delegate 和 event 观察者模式 这里面综合了几本书的资料. 需求 有这么个项目: 需求是这样的: 一个气象站, 有三个传感器(温度, 湿度, 气压), 有一个WeatherData对象, ...

  2. 利用Underscore求数组的交集、并集和差集

    1 数组交集函数——intersection 数组的交集是指包含多个数组中的共同元素的一个数组,求数组的交集就是找出给定数组中的共有元素. 下面实现一个求两个数组交集的函数. 判断数组是够包含指定值, ...

  3. Linux总结(十二)set_uid set_gid stic_bit 软链接 硬链接

    一 set_uid 之前我们修改普通用户的登陆密码,都是以管理员身份在操作,比如我们在lv账户下,我们使用sudo passwd lv 重置lv账户密码,此时我们直接拿到root权限忽略掉了文件权限的 ...

  4. JavaScript小游戏--2048(移动端)

    HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享.今天为大家介绍的事件主 ...

  5. 当前线程不在单线程单元中,因此无法实例化 ActiveX 控件

    “/”应用程序中的服务器错误. 当前线程不在单线程单元中,因此无法实例化 ActiveX 控件“c552ea94-6fbb-11d5-a9c1-00104bb6fc1c”. 说明: 执行当前 Web ...

  6. 【Nginx】使用Nginx作为Http代理的配置文件

    请看配置文件中的注释~ #user nobody; worker_processes 1; #pid logs/nginx.pid; events { worker_connections 1024; ...

  7. NHibernate参考文档、下载地址

    没有中文版哦,在线NHibernate参考文档:http://nhforge.org/doc/nh/en/获取地址:http://sourceforge.net/projects/nhibernate ...

  8. sql server 获取存储过程,表值,标量函数的参数

    所有的参数都是存在 sys.parameters 这个表中的,我们可以仿造 sql得到表中的列信息 这篇中的sql语句(提示:我们在表值函数中创建的表,最后我们是返回这个表的,我们可以用这个sql语句 ...

  9. mvc 页面 去掉转义字符

    mvc 页面 去掉转义字符   mvc 后台返回json数据,用ViewBag 传回前台页面,但是传到前台页面的时候,带有转义字符.一直想去掉这个转义字符,苦恼了好久. 解决方案: mvc 页面有个这 ...

  10. 端午节佳节从CSDN博客搬家来这,请多多指教

    端午节佳节从CSDN博客搬家来博客园,请多多指教