未在mongoengine

时间:2017-04-26 06:39:58

标签: python pymongo mongoengine

使用python Mongoengine我正在尝试创建数据库并将文档添加到不同的数据库。以下是我尝试这样做的方法:

from mongoengine import *

class MongoDataAccessObject():
    # method to connect to the database and initialize the tables etc.
    def __init__(self, my_env, helperObj):
        print "initializing db for the environment ", my_env
        self.con = None
        self.dbName = my_env
        self.helper_obj = helperObj

        try:
            self.con = connect(db=self.dbName)
        except Exception as e:
            print e

     def addRecord(self, document_object):
         document_object.save()

现在,我在创建上述类的对象时传递我想要创建的不同数据库的名称,并添加如下文档:

for my_env in list_of_envs:
        dao = MongoDataAccessObject(my_env, helper_object)
        dao.addRecord(myDocument)

现在有两个问题:

  1. 由于某些原因,我的所有文档都被添加到同一个DB中(第一个文件是在MongoDataAccessObject对象创建时传递的。我假设每次创建一个新对象时,每次都传递一个不同的db名称,应该为传递的新数据库创建一个新连接,并将文档添加到当前连接到的数据库中。
  2. 要验证我是否实际连接到有问题的数据库,我找不到连接对象上的get_database_name()方法。有没有办法验证我是否连接到正在传递的数据库名称?
  3. 好的做了一些研究并发现了这个: https://github.com/MongoEngine/mongoengine/issues/605

    在iptyhon中尝试过这样:

    from mongoengine import *
    import datetime
    
    class Page(Document):
        title = StringField(max_length=200, required=True)
        date_modified = DateTimeField(default=datetime.datetime.now)
    
    def switch(model, db):
        model._meta['db_alias'] = db
        # must set _collection to none so it is re-evaluated
        model._collection = None
        return model
    
    register_connection('default', name='testing')
    register_connection('mycon', name='db1')
    page = Page(title="Test Page")
    page = switch(page, 'mycon')
    page.save()
    

    这可以工作并创建一个名为db1的数据库并将文档存储在那里。

    现在我再次这样做:

    register_connection('mycon2', name='db2')
    page = Page(title="Test Page")
    page = switch(page, 'mycon2')
    page.save()
    

    与我的期望相反,这次没有创建db2(从mongo客户端和Robomongo都检查过),但文档已成功保存。想知道文件在哪里得到了保存呢?

    所以要想通过以下小改动重复上述练习:

    register_connection('mycon2', name='db2')
    page = Page(title="Test Page")
    page = switch(page, 'mycon2')
    x = page.save()
    # did a dir(x) and found that there is _get_db, so tried it out as below
    x._get_db()
    

    ,输出结果为:

      

    数据库(MongoClient(host = ['localhost:27017'],document_class = dict,tz_aware = False,connect = True,read_preference = Primary()),u'db2')

    我想这意味着文档保存在名为db2的数据库中。但是这个db2在哪里?为什么我不能通过mongo客户端甚至Robomongo等看到它?

1 个答案:

答案 0 :(得分:0)

最后,我能找到实现上述目标的唯一方法是通过MongoEngine提供的上下文管理器 with 语句,这里也有详细记录:http://docs.mongoengine.org/guide/connecting.html#switch-database

我在上面的代码中执行此操作的方式是这样的:

在第一次调用db时,需要创建一个默认数据库,该别名应该具有默认的别名。只有这样才能创建另一个别名,否则Mongoengine会抛出错误,指出没有找到默认数据库。

为此,在创建第一个db对象时,会向 __ init__of MongoDataAccessObject发送一个False标志 所以要做到这一点,MongoDataAccessObject也改为这样:

class MongoDataAccessObject():
    # method to connect to the database and initialize the tables etc.
    def __init__(self, my_env, helperObj, is_default_db_set):
        print "initializing db for the environment ", my_env
        self.con = None
        self.dbName = my_env
        self.helper_obj = helperObj
        self.db_alias = my_env
        self.is_default_db_set = is_default_db_set

        try:
            # all of this part with the is_default_db_set  and register_connection() is needed because MongoEngine does not 
            # provide a simple way of changing dbs or switching db connections. The only way to do it is through the switch_db()
            # context manager they provide (which has been used in the addRecord() below)
            if not self.is_default_db_set:
                self.con = connect(db=self.dbName, alias='default')
            else:
                # register_connection(alias_name, db_name)
                register_connection(self.db_alias, self.dbName)

        except Exception as e:
            print e

addRecord()也被修改为:

def addRecord(self, document_object):
         with switch_db(model_object, self.db_alias) as model_object:
                 document_object = model_object()
                 document_object.save()

以上部分:

for my_env in list_of_envs:
        dao = MongoDataAccessObject(my_env, helper_object)
        dao.addRecord(myDocument)

也被修改为:

for my_env in list_of_envs:
        dao = MongoDataAccessObject(my_env,helper_object,mongo_default_db_flag)
        dao.addRecord(myDocument)

这似乎对我有用。