最新消息:20190717 VPS服务器:Vultr新加坡,WordPress主题:大前端D8,统一介绍入口:关于

【已解决】pymongo中用MongoClient去连接远程加了权限控制的mongoDB

MongoDB crifan 199浏览 0评论
折腾:
【已解决】PyCharm连接远程添加security的authorization的MongoDB出错:com.mongodb.MongoCommandExceptions: Command failed with error 13
期间,去试试
结果:
mongodbUri = "mongodb://%s:%[email protected]%s" % (quote_plus("gridfs"), quote_plus("pwd"), quote_plus("xxx:27017"))
会报错:
Authentication failed
而换成:
mongodbUri = "mongodb://%s:%[email protected]%s" % (quote_plus("gridfs"), quote_plus("pwd"), quote_plus("xxx:27017/gridfs"))
会报错:
ValueError: Port must be an integer between 0 and 65535: 27017/gridfs
经过尝试发现:
代码中,用MongoClient主动加上参数authSource指定要验证的数据库:
(类似于参数–authenticationDatabase)
mongoClient = MongoClient(
    host="xxx",
    port=27017,
    username="gridfs",
    password="pwd",
    authSource="gridfs"
)
logging.info("mongoClient=%s", mongoClient)

gridfsDb = mongoClient.gridfs
logging.info("gridfsDb=%s", gridfsDb)

fsCollection = GridFS(gridfsDb)
logging.info("fsCollection=%s", fsCollection)
后才能有对应的读写权限:
而之前的:
mongodbUri = "mongodb://%s:%[email protected]%s" % (quote_plus("gridfs"), quote_plus("pwd"), quote_plus("xxx:27017/gridfs"))

# 
'
mongodb://gridfs:N%[email protected]%3A27017%2Fgridfs
’
mongoClient = MongoClient(mongodbUri)
虽然uri的写法,符合:
mongo_client – Tools for connecting to MongoDB — PyMongo 3.6.1 documentation
“* authSource: The database to authenticate on. Defaults to the database specified in the URI, if provided, or to “admin”.”
中说的,把要验证的数据库放在了uri
Connection String URI Format — MongoDB Manual 3.6
中了,但是却会报错:
ValueError: Port must be an integer between 0 and 65535: 27017/gridfs
好像是bug??
不过,反正是通过加了参数,是可以正常有权限操作的。
但是,还是再去试试,把:
ongodbUri = "mongodb://%s:%[email protected]%s" % (quote_plus("gridfs"), quote_plus("pwd"), quote_plus("xxx:27017/gridfs"))
改造一下:
mongodbUri = "mongodb://%s:%[email protected]%s:%s/%s" % (
    quote_plus("gridfs"), \
    quote_plus("pwd"), \
    "xxx", \
    27017, \
    "gridfs" \
)

mongoClient = MongoClient(mongodbUri)
然后发现也是可以正常有权限操作的:
-》证明之前的uri的写法,把端口号:数据库名字,即:
27017/gridfs
一起quote_plus,导致人家MongoClient内部解析端口发现端口叫做:
27017/gridfs
而不是
27017
所以报错的
-》属于自己使用不当
-〉MongoClient是可以正常的,在uri中指定要验证的数据库的
-》验证成功后,即可读写等操作。
【总结】
在远程MongoDB添加了访问权限控制后,
此处Python的driver:PyMongo中,可以通过uri,也可以通过参数,去验证用户,去登录并操作数据库的。
方法1: 在uri中指定用户名,密码,要验证的数据库
mongodbUri = "mongodb://%s:%[email protected]%s:%s/%s" % (
    quote_plus("gridfs"), \
    quote_plus("pwd"), \
    "xxx", \
    27017, \
    "gridfs" \
)
#'mongodb://gridfs:N%[email protected]:27017/gridfs
’
mongoClient = MongoClient(mongodbUri)
-》优化后为:
MongoHostRemote = "xxx"
MongoHostLocal = "localhost"
# MongoHostLocal = "127.0.0.1"
# MongoHost = MongoHostRemote
MongoHost = MongoHostLocal

MongoPort = 27017

# MongoUseAuth = True
MongoUseAuth = False

# with auth
MongoUsername = "gridfs"
MongoPassword = "pwd"
MongoAuthenticationDatabase = "gridfs"

mongodbUri = ""
if MongoUseAuth :
    mongodbUri = "mongodb://%s:%[email protected]%s:%s/%s" % (
        quote_plus(MongoUsername), \
        quote_plus(MongoPassword), \
        MongoHost, \
        MongoPort, \
        MongoAuthenticationDatabase \
    )
    #'mongodb://gridfs:N%[email protected]:27017/gridfs'
else:
    mongodbUri = "mongodb://%s:%s" % (
        MongoHost, \
        MongoPort
    )
    #'mongodb://localhost:27017'
    #'mongodb://xxx:27017'

mongoClient = MongoClient(mongodbUri)
方法2: 在MongoClient的参数中指定用户名,密码,要验证的数据库
mongoClient = MongoClient(
    host="xxx",
    port=27017,
    username="gridfs",
    password="pwd",
    authSource="gridfs"
)
均可正常,用:用户名+密码+验证数据库,通过验证,后续可正常读写操作数据库。
心得:
之前不小心用:
mongodbUri = "mongodb://%s:%[email protected]%s" % (quote_plus("gridfs"), quote_plus("pwd"), quote_plus("xxx:27017/gridfs"))
而把端口号连带要验证的数据库:
27017/gridfs
encode为:
27017%2Fgridfs
导致MongoClient内部以为port参数是
(27017%2Fgridfs 解码后的)
27017/gridfs
-》而不是正常的:27017
-〉从而导致报错:
ValueError: Port must be an integer between 0 and 65535: 27017/gridfs
-》提醒我们,对于mongo的uri中的其他的值,包括端口号和要验证的数据库等值,不要过度的,去编码本身不需要编码的值,从而导致出错。
-》正常的需要编码的,一般只有:
用户名和密码
尤其是密码,此处包含了非正常字符@,所以才要用到:
quote_plus(“[email protected]”)
的。
-》其他没有包含特殊字符,包括此处上面的
quote_plus(“gridfs”)
其实完全没有必要,直接写成:
gridfs
就可以了。

转载请注明:在路上 » 【已解决】pymongo中用MongoClient去连接远程加了权限控制的mongoDB

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
86 queries in 0.113 seconds, using 20.73MB memory