【问题标题】:Check MongoDB database instance is a replica set检查 MongoDB 数据库实例是副本集
【发布时间】:2021-02-22 19:26:58
【问题描述】:

我正在为使用事务的函数编写测试。

Transactions only work on replica sets or mongos:

pymongo.errors.OperationFailure: Transaction numbers are only allowed on a replica set member or mongos, full error: {'ok': 0.0, 'errmsg': 'Transaction numbers are only allowed on a replica set member or mongos', 'code': 20, 'codeName': 'IllegalOperation'}

如果数据库是独立的 mongod 实例,我希望跳过这些测试。

如何从 Python 代码(例如,使用 pymongo 函数)检查我正在使用适当的环境?

我可以将 CI 管道配置为使用副本集。我可以并且确实在我的机器上进行了配置。但我不希望这几个测试对潜在贡献者造成麻烦,所以我宁愿跳过它们。

或者,我可以捕获OperationFailure 并尝试通过匹配字符串来确保它正是上面的错误,而不是另一个OperationFailure,但这将是一个抱歉的解决方法。


也许我可以使用类似的东西

MongoClient('localhost', 27017).admin.command("replSetGetStatus")

在经历艰难的反复试验之前,我很乐意获得明智的建议。

【问题讨论】:

    标签: python mongodb pymongo


    【解决方案1】:

    这是一种检查 MongoDB 实例是否为副本集的方法:

    每个mongod 实例都有自己的local 数据库(local 是数据库名称),用于存储复制过程中使用的数据以及其他特定于实例的数据。 local 数据库中的 system.replset 集合将副本集的配置对象作为其单个文档保存。

    要查看此配置,请从 mongo shell 发出 rs.conf()。你也可以直接查询这个集合(见下面方法中使用的代码)。

    client = pymongo.MongoClient(url)
    collection = client.local.system.replset
    try:
        doc = collection.find()[0]
        print(doc['_id'])
        return True
    except Exception as e:
        print("local.system.replset doesn't exist: " + str(e))
        return False
    

    请注意,如果光标为空,即system.replset 集合在local 数据库中不存在并且查询失败(并且对于独立 实例)。

    在代码中,doc['_id'] 是副本集名称。

    【讨论】:

    • 谢谢。为什么不只是return "system.replset" in client.local.list_collection_names()
    • 有效问题。我想依赖以下事实:“local.system.replset 将副本集的配置对象作为其单个文档。”。不知何故,查询该集合并查看是否有引用副本集配置的此类文档听起来很有保证。
    • 单机的情况下,光标是空的,对吧?为什么不是return bool(client.local.system.replset.find()),如果光标不为空,它应该返回True?
    • 值得尝试各种查询,看看结果是否一致。
    【解决方案2】:

    这是我想出的:

    def is_replica_set():
        try:
            pymongo.MongoClient().admin.command("replSetGetStatus")
            return True
        except pymongo.errors.OperationFailure:
            return False
    
    
    @pytest.mark.skipif(not is_replica_set(), reason="Replica set required")
    def test_transaction():
        ...
    

    【讨论】:

      【解决方案3】:

      发送{ismaster: 1} 命令并按照规则here 解析响应。

      副本集节点将在响应中设置setName 字段。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-13
        • 1970-01-01
        • 1970-01-01
        • 2015-08-17
        • 1970-01-01
        • 2012-10-08
        • 1970-01-01
        • 2015-06-27
        相关资源
        最近更新 更多