【day7】pymongo模块/flask接口 ValueError: updat ValueError: update only works with $ operators

 

1 pymongo模块

            mongodb是非关系型数据库,它是放在磁盘里,没有sql语句,也没有表结构,没有限制,随便向里面插入数据。

它是一个可视化工具,可以看数据,也可以改数据

1.1连接mongodb

1 client = pymongo.MongoClient(host='xxxx',port=27017,username="user name", password="pass/word")

1.2创建数据库

collection = client['spz']['stu_info']
1 db = client['spz']#选择数据库,如果不存在则自动新建一个数据库
2 collection = db['stu_info']#指定集合名称,如果不存,会自动创建集合

1.3插入数据

1 collection.insert({'name':'xhy','sex':''})#集合stu_info如果不存在则自动创建,insert的数据类型为字典,该字典作为集合stu_info独立的一个object,存储相应的键值对
2 collection.insert({'name':'xhy','sex':''})#object的键值对允许重复,ojbectid不同
3 collection.insert({'name':'地址','url':'http://www.baidu.com','title':'baidu','addr':'北京'})#每一个object的键值名称长度可以不相同

1.4修改数据

  • 更新一条  update({condition},{将查询到的整个object覆盖为此处的值})
 
 
 data = collection.find()
1 print('更新前======',list(data))
2 collection.update({'name':'xhy'},{'name':'hhh','class':'spz'})#{'name':'xhy'}是查询条件(可以是多个条件);第二个参数是指查询到的object修改为该字典
3 data1 = collection.find({'name':'xhy'})
4 data2 = collection.find({'name':'hhh'}) 
5 print('更新后======',list(data1)) 
6 print('更新后======',list(data2))
1 更新前====== [{'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d9945644c07302cd0c2a0')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d9945644c07302cd0c2a1')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d9979644c072e08a4a50e')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d9979644c072e08a4a50f')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d99f8644c072998021bca')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d99f8644c072998021bcb')}]
2 更新后====== [{'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d9945644c07302cd0c2a1')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d9979644c072e08a4a50e')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d9979644c072e08a4a50f')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d99f8644c072998021bca')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d99f8644c072998021bcb')}]
3 更新后====== [{'name': 'hhh', '_id': ObjectId('5b4d9945644c07302cd0c2a0'), 'class': 'spz'}]
4 
5 View Result

更新多条  update({condition},{"$set":{在原来数据的基础上修改},multi=True)

  •  $set就是代表在原来数据的基础上修改。如果不用它的话,就是直接把原来的数据覆盖了。

  • 使用multi=True,如果不使用$的话,会报错:ValueError: updat
1 print('更新前======',list(data))
2 collection.update({'name':'xhy'},{"$set":{'name':'hhh','class':'spz'}},multi=True)
3 data1 = collection.find({'name':'xhy'})
4 data2 = collection.find({'name':'hhh'})
5 print('更新后======',list(data1))
6 print('更新后======',list(data2))
1 更新前====== [{'name': 'xhy', 'sex': '', '_id': ObjectId('5b4d9fc2644c072d60676f59')}, {'name': 'xhy', 'sex': '', '_id': ObjectId('5b4d9fc2644c072d60676f5a')}]
2 更新后====== []
3 更新后====== [{'name': 'hhh', 'sex': '', '_id': ObjectId('5b4d9fc2644c072d60676f59'), 'class': 'spz'}, {'name': 'hhh', 'sex': '', '_id': ObjectId('5b4d9fc2644c072d60676f5a'), 'class': 'spz'}]

更新多条  update_many({condition},{"$set":{在原来数据的基础上修改})

1 print('更新前======',list(data))
2 collection.update_many({'name':'xhy'},{"$set":{'name':'hhh','class':'spz'}})
3 data1 = collection.find({'name':'xhy'})
4 data2 = collection.find({'name':'hhh'})
5 print('更新后======',list(data1))
6 print('更新后======',list(data2))
1 更新前====== [{'name': 'xhy', 'sex': '', '_id': ObjectId('5b4da17b644c071cfcdd3c9a')}, {'name': 'xhy', 'sex': '', '_id': ObjectId('5b4da17b644c071cfcdd3c9b')}]
2 更新后====== []
3 更新后====== [{'name': 'hhh', 'sex': '', '_id': ObjectId('5b4da17b644c071cfcdd3c9a'), 'class': 'spz'}, {'name': 'hhh', 'sex': '', '_id': ObjectId('5b4da17b644c071cfcdd3c9b'), 'class': 'spz'}]

1.5删除数据

  • 删除一条  delete_one({'key1':'value1','key2':'value2',...})
1 print('3=====删除前',list(data))
2 collection.delete_one({'name':'xhy'})#如果有多条的话,只会删掉1条
3 data = collection.find({'name':'xhy'})
4 print('3=====删除后',list(data))
1 3=====删除前 [{'sex': '', '_id': ObjectId('5b4d97ce644c07344826bc05'), 'name': 'xhy'}, {'sex': '', '_id': ObjectId('5b4d9800644c0705c4269eba'), 'name': 'xhy'}, {'sex': '', '_id': ObjectId('5b4d9800644c0705c4269ebb'), 'name': 'xhy'}]
2 3=====删除后 [{'sex': '', '_id': ObjectId('5b4d9800644c0705c4269eba'), 'name': 'xhy'}, {'sex': '', '_id': ObjectId('5b4d9800644c0705c4269ebb'), 'name': 'xhy'}]
  •  删除多条  delete_many({'key1':'value1','key2':'value2',...})
1 print('3=====删除前',list(data))
2 collection.delete_many({'name':'xhy'})#如果有多条的话,会删掉所有匹配数据
3 data = collection.find({'name':'xhy'})#注意游标取值
4 print('3=====删除后',list(data))
1 3=====删除前 [{'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d9800644c0705c4269eba')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d9800644c0705c4269ebb')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d98ba644c0713c88d8e4f')}, {'sex': '', 'name': 'xhy', '_id': ObjectId('5b4d98ba644c0713c88d8e50')}]
2 3=====删除后 []

1.6查询数据

  • find返回结果是一个游标对象<pymongo.cursor.Cursor object at xxxxx>,需要使用list(data)转成列表,才可正常打印出结果。注意游标指针的位置。
  • 注意多个条件是指多个key:value键对放在一个字典里。表示这些key:value都在一个object中出现。
1 data1 = collection.find()#不指定条件
 2 data2 = collection.find({'title':'baidu.com'})#指定条件不存在
 3 data3 = collection.find({'name':'xhy'})#指定一个条件
 4 data4 = collection.find({'title':'baidu','name':'地址'})#指定多个条件(一个object里必须符合所有条件)
 5 print('1不指定条件=====',[data for data in data1])
 6 print('2指定条件不存在=====',list(data2))
 7 for data in data3:#循环取查询结果的每一个元素(即每一个字典)
 8     print('3指定一个条件=====',data)
 9 print('4指定多个条件=====',list(data4))
10 print('5游标在末尾=====',list(data4))#注意当游标指针在末尾时,再次取值会取不到
1 1不指定条件===== [{'name': 'xhy', 'sex': '', '_id': ObjectId('5b4d5d86644c071c58a27f9a')}, {'name': 'xhy', 'sex': '', '_id': ObjectId('5b4d5eee644c0738948d0beb')}, {'url': 'http://www.baidu.com', 'name': '地址', 'addr': '北京', 'title': 'baidu', '_id': ObjectId('5b4d5eee644c0738948d0bec')}]
2 2不指定条件===== []
3 3指定一个条件===== {'name': 'xhy', 'sex': '', '_id': ObjectId('5b4d5d86644c071c58a27f9a')}
4 3指定一个条件===== {'name': 'xhy', 'sex': '', '_id': ObjectId('5b4d5eee644c0738948d0beb')}
5 4指定多个条件===== [{'url': 'http://www.baidu.com', 'name': '地址', 'addr': '北京', 'title': 'baidu', '_id': ObjectId('5b4d5eee644c0738948d0bec')}]
6 5游标在末尾===== []
7 
8 View Result

2 flask模块

  • flask是开源的web框架,可以用来接口开发
  • 接口开发的目的:
    • 知道接口是怎么开发的
    • 避免别人直接操作数据库
    • mock服务(模拟服务,如挡板应用)

2.1创建并启动服务

  • server = flask.Flask(__name__)  创建服务

  • server.run(port=xxxx)  运行服务
    • port 默认值参数,默认5000端口
    • debug  默认值参数,设置参数为debug=True,则修改完py文件后保存,会自动重启服务。方便调试。  
    • pycharm重启服务注意事项:不要重复右键run文件,正确的做法是保证只有一个服务在启动,点击重启按钮重启服务
# 先安装第三方库
# pip install flask
1 import flask
2 server = flask.Flask(__name__)#把当前这个python文件当作一个服务
3 server.run()#启动服务
1  * Serving Flask app "test" (lazy loading)
2  * Environment: production
3    WARNING: Do not use the development server in a production environment.
4    Use a production WSGI server instead.
5  * Debug mode: off
6  * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
View Result

2.2定义接口

  • @server.route('/接口访问名称',methods=['get','post'])。其后定义一个函数,则该函数就成为服务里的一个接口,可以使用http://host:<port>/implement_name访问

    • 接口访问名称:可以与函数的名称不一样的。
    • methods: 接口支持的请求方法。methods值必须是一个列表类型。
 

定义一个简单的接口

1 import flask,json
2 server = flask.Flask(__name__)#把当前这个python文件当作一个服务
3 @server.route('/login',methods=['get','post'])
4 def login():
5     res = {'code': 1000, 'msg': '登录成功!', 'sign': 'snxxxxxxxx'}
6     return json.dumps(res,ensure_ascii=False)#字典转成json串, ensure_ascii=False返回的json串里没有乱码
7 server.run(port=5001)

2.3传参

2.3.1  flask.request.values
  • params= flask.request.args #使用request.args.get不能获取到body里传的参数值(服务会报错),只能获取url后拼接的参数值

    扫描二维码关注公众号,回复: 2229615 查看本文章
  • params= flask.request.values #使用request.values.get可以获取url及body里传递的参数值。推荐使用。

   返回CombinedMultiDict类型,如CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([('pwd', '123456'), ('usr', 'hwm')])])

  • params.get('param_name')  #param_name是参数名称。get用于获取具体参数值

 登陆接口小例子如下:

 1 # http://118.24.3.40/api/product/all
 2 import flask,json,hashlib,pymysql
 3 server=flask.Flask(__name__) #能帮忙启动一个服务,把当前python文件当做一个服务
 4 @server.route('/login',methods=['get','post']) #装饰器,下面的函数就变成了一个接口
 5 def taotao():
 6     #获取请求参数,注:request.args 使用postman中的post取不到数据,它需要用request.values
 7     username=flask.request.args.get('username') #是从客户端(postman)发过来的数据
 8     pwd=flask.request.args.get('password')
 9     # flask.request.cookies.get('xxxx') #获取cookies
10     # flask.request.headers.get('xxxx') #获取headers
11     # json_data=flask.request.json('username') #这个是获取入参为json类型
12     # print('json_data....',json_data)
13     if username=='nhy' and pwd=='123456':
14         res={'code':1000,'msg':'登陆成功','sign':'sseeddreww134trg'}
15     else:
16         res={'code':2000,'msg':'账号/密码错误'}
17     return  json.dumps(res,ensure_ascii=False) #ensure_ascii=False显示中文

使用postman传参数,返回测试结果如下:

1. 使用flask.request.args.get(xx) body中,传入参数,结果会报错

 2. 使用flask.request.args.get(xx) 在url中,传入参数,结果会成功

3. username=flask.request.values.get('username') #------ 推介 使用这个方法 

如果使用values的话,不管是 boby中传数据,还是从url中传数据,都会成功。

猜你喜欢

转载自www.cnblogs.com/xhybk/p/9332664.html