2020年7月18日 14:39 by wst
database最近打算抓取一些数据进行分析,由于之前用过mongo,觉得不错。这次决定采用mongo存储数据,图的就是方便!
目的很简单,只是存取数据,但这中间遇到了一些问题,下面一一列举:
1. 前提是已安装并启动数据,这里使用docker安装的mongo,命令如下:
# 拉取mongo镜像
docker pull mongo:latest
# 创建并运行实例
docker run -itd --name mongo -p 27017:27017 mongo --auth
2. 进入mongo,在admin中创建用户:
docker exec -it mongo mongo admin
# 创建一个名为 admin,密码为 123456 的用户。
> db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'}]});
# 尝试使用上面创建的用户信息进行连接。
> db.auth('admin', '123456')
3. 创建普通用户,使其对应库db001, db002
>db.createUser({
user:"wst",
pwd:"123456",
roles:[{
role:"dbAdmin",
db:"db001"
},{
role:"readWrite",
db:"db002"
}]
})
4. 运行如下(python3)代码,读写数据库db001
from pymongo import MongoClient
class StoreMongo(object):
def __init__(self, host, port, user, password, database, collection):
self.client = MongoClient(host, port)
self.client.admin.authenticate(user, password)
self.database = database
self.collection = collection
def get_cursor(self):
db = self.client[self.database]
collection = db[self.collection]
return collection
def coll_names(self):
db = self.client[self.database]
return db.collection_names()
def store_data(self, dataset):
collection = self.get_cursor()
for data in dataset:
collection.save(data)
def upsert(self, con, dic):
collection = self.get_cursor()
collection.update(con, dic, True)
def delete(self, query):
collection = self.get_cursor()
collection.delete_one(query)
def results_count(self, query):
collection = self.get_cursor()
return collection.find(query).count()
def search_data(self, query, limit={"_id": 0}):
rs = self.client[self.database][self.collection].find(query, limit)
return rs
def collection_count(self):
return self.client[self.database][self.collection].count()
def __del__(self):
self.client.close()
if __name__ == "__main__":
host = '10.160.15.209' # 如果在阿里云上运行使用 10.160.15.209
port = 27017 #请根据实际情况修改
user = "wst" #请根据实际情况修改
password = "123456" #请根据实际情况修改
database = 'db001' #请根据实际情况修改
collection = 'mydata' #请根据实际情况修改
obj = StoreMongo(host, port, user, password, database, collection)
# 存储单条数据
obj.store_data([{"name": "xiaoming", "sex": "male", "age": 18}, ])
# 存储多条数据
obj.store_data([{"name": "lingling", "sex": "female", "age": 16},
{"name": "zhangsan", "sex": "male", "age": 20}])
res = obj.search_data({})
print(res.next())
print("Done!")
奇怪的事情发生了,写入报错,我已经是dbAdmin角色了,为什么不能操作db001库呢?
5. 后来查询发现adAdmin并不具有读写权限,于是执行如下命令添加readWrite角色。
docker exec -it mongo mongo admin
>db.auth('admin', '123456')
>db.grantRolesToUser("wst",[{ role : "readWrite", db : "db001"}])
再次执行上面的python代码,已经能正确读写数据!
1. 无法进入数据库。
进入mongo之后(这里默认进入的是admin库),没有进行认证 db.auth('admin', '123456'),无法进行后续操作。
2. 无法操作自己的库。
use db001 进入自己库,然后再认证db.auth('wst', '123456'), 发现报错。实际应该:在admin库中执行db.auth('wst', '123456'),然后再use db001进入自己的库。最终查看自己的数据db.mydata.find()
1. 开启认证的mongo服务,进入时需要认证;
2. 并不是所有带admin字眼的角色都能读写数据,详细可见这里;
3. 要想进入自己的库,得先在admin库中认证,然后进入自己的库;
docker创建mongo实例、创建管理员用户、给用户添加权限;
后记:对于更多的用户操作(比如修改密码、撤销权限、更新用户),参考这里。