mongoengine支持程序同时连接多个数据库,这些数据库可以位于一个或多个mongo之中,通过alias名称区分不同的连接即可。

可以通过switch_db切换到不同的数据库,进行读写操作,switch_db其实是一个上下文管理器,通过和with语句一起使用,能够保证切换数据库的影响范围。

由于个人电脑上没有安装mongodb,以下代码示例中访问的mongodb通过mongoengine提供的mock mongodb替代,只需要在connect函数参数中加上is_mock=True参数,并且安装有mongomock package(pip install mongomock)即可。

 #!/usr/bin/env python
# coding=utf-8
from mongoengine import connect
from mongoengine.document import Document
from mongoengine.fields import StringField, IntField
from mongoengine.context_managers import switch_db # 连接不同db
connect(alias='testdbA', is_mock=True)
connect(alias='testdbB', is_mock=True)
connect(alias='testdbC', is_mock=True) class User(Document):
meta = {
# db_alias用于指定User绑定的mongo连接,和connect函数中的alias对应
'db_alias': 'testdbA',
}
uname = StringField(max_length=63)
uid = StringField(max_length=64)
age = IntField(default=0) def create_record(uname, uid, age):
user = User()
user.uname = uname
user.uid = uid
user.age = age
return user def print_records(records):
# 输出User类此时绑定的db连接名称,并输出其记录个数
records = list(User.objects.all())
print('{} count:{}, records:'.format(User._meta['db_alias'], len(records)))
for rc in records:
print(' {}|{}|{}'.format(rc['uname'], rc['uid'], rc['age'])) records = list(User.objects.all())
print_records(records)
create_record('Ace', 'AX001', 10).save()
print_records(records) # switch到testdbB连接
with switch_db(User, 'testdbB'):
print_records(records)
create_record('Bob', 'BX001', 11).save()
print_records(records) # switch到testdbC连接
with switch_db(User, 'testdbC'):
print_records(records)
create_record('Carl', 'CX001', 12).save()
print_records(records)

运行结果如下:

$ python mongo_test.py
testdbA count:0, records:
testdbA count:1, records:
Ace|AX001|10
testdbB count:0, records:
testdbB count:1, records:
Bob|BX001|11
testdbC count:0, records:
testdbC count:1, records:
Carl|CX001|12

switch_db其实就是一个简单的上下文管理器,源码位于mongoengine/context_managers.py当中,其实就是在switch_db对象初始化时、进入with代码块前、离开with代码块后,通过改变db_alias和collection两个字段对应的取值,实现了不同mongodb连接的切换,代码简单注释版本如下:

 class switch_db(object):
"""switch_db alias context manager. Example :: # Register connections
register_connection('default', 'mongoenginetest')
register_connection('testdb-1', 'mongoenginetest2') class Group(Document):
name = StringField() Group(name='test').save() # Saves in the default db with switch_db(Group, 'testdb-1') as Group:
Group(name='hello testdb!').save() # Saves in testdb-1
""" def __init__(self, cls, db_alias):
"""Construct the switch_db context manager :param cls: the class to change the registered db
:param db_alias: the name of the specific database to use
"""
self.cls = cls
# 存储切换前的collection
self.collection = cls._get_collection()
# 设置为要切换的db连接名称
self.db_alias = db_alias
# 存储切换前的原db连接名称
self.ori_db_alias = cls._meta.get('db_alias', DEFAULT_CONNECTION_NAME)
def __enter__(self):
"""Change the db_alias and clear the cached collection."""
# 进入with代码块前触发
# 修改为本次指定的db连接名称
self.cls._meta['db_alias'] = self.db_alias
# 将collection置为None,于是之后会重新根据新的db连接获取collection
self.cls._collection = None
return self.cls def __exit__(self, t, value, traceback):
"""Reset the db_alias and collection."""
# 退出with代码块后触发
# 恢复为切换前的db连接名称
self.cls._meta['db_alias'] = self.ori_db_alias
# 恢复为切换前的collection
self.cls._collection = self.collection

python通过mongoengine中connect函数连接多个数据库的更多相关文章

  1. python 在机器学习中应用函数

    浅述python中argsort()函数的用法 (1).先定义一个array数据 1 import numpy as np 2 x=np.array([1,4,3,-1,6,9]) (2).现在我们可 ...

  2. python开发_python中的函数定义

    下面是我做的几个用列: #python中的函数定义,使用和传参 def_str = '''\ python中的函数以如下形式声明: def 函数名称([参数1,参数2,参数3......]): 执行语 ...

  3. python unittest框架中addCleanup函数详解

    接上一篇doCleanups说明,这次介绍下另一个很好用的函数:addCleanup 还是老规矩,看官方文档说明: addCleanup(function, *args, **kwargs)¶ Add ...

  4. 一、MySQL中的索引 二、MySQL中的函数 三、MySQL数据库的备份和恢复 四、数据库设计和优化(重点)

    一.MySQL中的索引###<1>索引的概念 索引就是一种数据结构(高效获取数据),在mysql中以文件的方式存在.存储建立了索引列的地址或者指向. 文件 :(以某种数据 结构存放) 存放 ...

  5. python 利用matplotlib中imshow()函数绘图

    matplotlib 是python最著名的2D绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中.通过简单的绘图语 ...

  6. (转)python类class中_init_函数以及参数self的简单解释

    1)_init_函数(方法) #-*- encoding:utf-8 -*- class NewClass(object): def __init__(self,name): print self s ...

  7. python和numpy中sum()函数的异同

    转载:https://blog.csdn.net/amuchena/article/details/89060798和https://www.runoob.com/python/python-func ...

  8. Python -- 使用模块中的函数

    在确定自己不会导入多个同名函数(从不同模块导入)的情况下,你可能不希望在每次调用函数的时候,都要写上模块的名字.那么,可以使用import命令的另外一种形式: >>> from ma ...

  9. 关于python使用threadpool中的函数单个参数和多个参数用法举例

    1.对单个元素的函数使用线程池: # encoding:utf-8 __author__='xijun.gong' import threadpool def func(name): print 'h ...

随机推荐

  1. Linux的man手册共有以下几个章节

    Linux提供了丰富的帮助手册,当你需要查看某个命令的参数时不必到处上网查找,只要man一下即可. Linux的man手册共有以下几个章节: 1.Standard commands (标准命令) 2. ...

  2. nohup命令、setsid命令、Daemon(守护进程)简要梳理

    nohup命令 当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程.因此,我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新 ...

  3. C#图解教程读书笔记(第7章 类和继承)

    1.所有的类都继承自object 2.如何隐藏基类的成员 要隐藏一个继承的数据成员,需要声明一个新的相同类型的成员,并使用相同的名称. 通过在派生类中声明新的带有相同签名的函数成员,可以隐藏或掩盖继承 ...

  4. 记两个std接口equal_range,set_difference

    1.equal_range equal_range是C++ STL中的一种二分查找的算法,试图在已排序的[first,last)中寻找value,它返回一对迭代器i和j,其中i是在不破坏次序的前提下, ...

  5. 在Node中使用ES7新特征——async、await

    async与await两个关键字是在ES7中添加的新特征,旨在更加直观的书写异步函数,避免出现callback hell. callback hell是什么? readFileContents(&qu ...

  6. new ,malloc

    特征 new/delete malloc/free 分配内存的位置 自由存储区 堆 内存分配失败返回值 完整类型指针 void* 内存分配失败返回值 默认抛出异常 返回NULL 分配内存的大小 由编译 ...

  7. PHP基础系列(一) PHP字符串相关的函数分类整理

    PHP提供了非常丰富的自带函数,有人说PHP是一个大的函数库,在某种程度上我是非常认同这种观点的,这个也是PHP非常容易上手的原因之一.在使用PHP编程的时候,需要实现某一功能的时候,如果说php自带 ...

  8. 清除IE下input的叉叉

    很多时候,我们在开发过程中,设计师会在输入框后加上定制的清除图标,但是在IE下有IE自带的清除图标,肯定是不美观的. <style> ::-ms-clear, ::-ms-reveal{d ...

  9. MyBatis(10)逆向工程

    什么是逆向工程? 在学习的过程中会发现,需要我们写大量的sql语句 此时mybaatis官方为我们提供逆向工程可以针对单表自动生成的mybatis执行所需要的代码     使用方法:    MyBat ...

  10. 全局ajax的使用

    一.ajax介绍 详细介绍请看:http://www.runoob.com/ajax/ajax-tutorial.html AJAX = Asynchronous JavaScript and XML ...