python - 连接未创建到 mongoengine 中的新 dbname

标签 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)

现在这里有2个问题:

  1. 出于某种原因,我的所有文档不断被添加到同一个数据库中(第一个在创建 MongoDataAccessObject 对象时被传递。我假设每次创建一个新对象时,每次都传递不同的数据库名称,应该为传递的新数据库创建一个新连接,并且应该将文档添加到当前连接到的数据库中。
  2. 为了验证我是否真的连接到有问题的数据库,我在连接对象上找不到像 get_database_name() 这样的方法。有没有办法验证我是否连接到正在传递的数据库名称?

好的,做了更多的研究,发现了这个: 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()

输出是:

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

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

最佳答案

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

我在上面的代码中的做法是这样的:

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

所以要做到这一点,当第一个数据库对象被创建时,一个 False 标志被发送到 __init__of MongoDataAccessObject 为此,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)

这似乎适合我。

关于python - 连接未创建到 mongoengine 中的新 dbname,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43626773/

相关文章:

python - mongoengine - 嵌入式文档中的键索引?

python - 使用 vtkCamera 显式投影变换矩阵和 prop3D 可见性

python - 有没有办法动态改变文本颜色?

python - 用 pythons 内置的 map 函数替换函数

python - Mongodb : AutoReconnect, 连接被对端重置

python - 使用 Pymongo 更新 MongoDB 中的选定字段

python - 如何获得特征的权重

python - 如何使用 pymongo 更新值?

python - Mongoengine查询列表字段包含字符串匹配

python - 如何加快 mongoengine 查询速度