使用python为mysql实现restful接口


Posted in Python onJanuary 05, 2018

最近在做游戏服务分层的时候,一直想把mysql的访问独立成一个单独的服务DBGate,原因如下:

请求收拢到DBGate,可以使DBGate变为无状态的,方便横向扩展

当请求量或者存储量变大时,mysql需要做分库分表,DBGate可以内部直接处理,外界无感知

通过restful限制对数据请求的形式,仅支持简单的get/post/patch/put 进行增删改查,并不支持复杂查询。这个也是和游戏业务的特性有关,如果网站等需要复杂查询的业务,对此并不适合

DBGate使用多进程模式,方便控制与mysql之间的链接数,进行mysql访问量阀值保护

方便在DBGate上进行访问量统计,慢查询统计、权限控制等等一系列逻辑

目前是使用python,以后要使用其他语言进行mysql操作时,只要进行标准的http请求即可,不会出现不兼容的情况

当然坏处也是有的:

首当其冲就是单次请求的响应时间变长,毕竟中间加了一层服务,并且还是http格式

部署上比原来复杂了一些,很多对mysql直接操作的思维需要进行转变,一开始可能会有些不适

不过总的来说,还是利大于弊,所以最终还是决定搭建DBGate

当然,我们不可能去手工挨个写每个库表对应的restful服务,值得庆幸的是django和flask都提供了对应的解决方案,我们一个个介绍.

Flask

参考链接: flask-restless

flask-restless使用方法比较简单,我直接贴一下代码即可:

import datetime
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restless import APIManager
app = Flask(__name__)
db = SQLAlchemy(app)
restless = APIManager(app, flask_sqlalchemy_db=db)
class User(db.Model):
"""
user
"""
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(255), unique=True, nullable=False)
password = db.Column(db.String(255), nullable=False)
create_time = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
login_time = db.Column(db.DateTime)
restless.create_api(User, methods=['GET', 'POST', 'DELETE', 'PATCH', 'PUT'], results_per_page=100)
db.create_all()
if __name__ == '__main__':
app.run(port=25000)

其对应的restful操作如下:

获取用户列表: GET /user

添加用户: POST /user

获取单个用户: GET /user/1

覆盖单个用户: PUT /user/1

修改单个用户: PATCH /user/1

注意:

在http请求中,记得加入header: Content-Type: application/json

flask-restless中,PUT和PATCH一样,都是传入什么字段,只修改什么字段,不会完全覆盖

Django

参考链接: Django REST framework

Django用起来要更复杂一些,也因为django版自带了一个可视化的操作页面,如下:

QQ20140803 2

1. 在settings中添加:

REST_FRAMEWORK = {
# Use hyperlinked styles by default.
# Only used if the `serializer_class` attribute is not set on a view.
'DEFAULT_MODEL _SERIALIZER_CLASS':
'rest_framework.serializers .HyperlinkedModelSerializer',
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT _PERMISSION_CLASSES': [
#'rest_framework.permissions .DjangoModelPermissionsOrAnonReadOnly',
'rest_framework .permissions.IsAdminUser',
]
}

2. 通过startapp建立一个app: demo

3. 修改demo的models:

class User(models.Model):
# key是保留字
password = models.IntegerField()
nick = models.CharField(max_length=255)
create_time = models.DateTimeField(default=datetime.datetime.now)

4. 在demo下新建serializers.py

class User(models.Model):
# key是保留字
password = models.IntegerField()
nick = models.CharField(max_length=255)
create_time = models.DateTimeField(default=datetime.datetime.now)

5. 在demo下修改views.py

from django.shortcuts import render
from rest_framework import viewsets
from serializers import UserSerializer
from models import User
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer

6. 在demo下新建urls.py

import os.path
from django.conf.urls import patterns, include, url
from django.conf.urls.static import static
from django.conf import settings
import views
from rest_framework import routers
appname = os.path.basename (os.path.dirname(os.path.abspath(__file__)))
router = routers.DefaultRouter()
router.register('users', views.UserViewSet, appname)
urlpatterns = patterns('',
url(r'^', include(router.urls)),
)

7. 在mysite.urls下include demo.urls和rest_framework.urls

urlpatterns = patterns('',
url(r'^demo/', include('demo.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)

8. 执行初始化数据操作:

python manage.py syncdb

之后访问: http://127.0.0.1:8000/demo 即可看到如下界面了:

QQ20140803 1

对应的测试代码如下:

import json
import requests
from urlparse import urljoin
BASE_URL = 'http://127.0.0.1:16500/'
AUTH = ('admin', 'admin')
def test_get_user_list():
rsp = requests.get(urljoin(BASE_URL, '/demo/users/'), auth=AUTH, headers={
'Accept': 'application/json'
})
assert rsp.ok
def test_post_user_list():
json_data = dict(
password=0,
nick='oo',
create_time='2014-03-3T03:3:3'
)
rsp = requests.post(urljoin(BASE_URL, '/demo/users/'), auth=AUTH, headers={
'Accept': 'application/json',
'Content-Type': 'application/json',
}, data=json.dumps(json_data))
assert rsp.ok
def test_get_user():
rsp = requests.get(urljoin(BASE_URL, '/demo/users/1'), auth=AUTH, headers={
'Accept': 'application/json',
'Content-Type': 'application/json',
})
assert rsp.ok
def test_put_user():
json_data = dict(
password=100,
nick='xx',
create_time='2014-03-3T03:3:3'
)
# 注意最后的 /
rsp = requests.put(urljoin(BASE_URL, '/demo/users/1/'), auth=AUTH, headers={
'Accept': 'application/json',
'Content-Type': 'application/json',
}, data=json.dumps(json_data),
)
assert rsp.ok, rsp.status_code
def test_patch_user():
json_data = dict(
password=300,
)
rsp = requests.patch(urljoin(BASE_URL, '/demo/users/1/'), auth=AUTH, headers={
'Accept': 'application/json',
'Content-Type': 'application/json',
}, data=json.dumps(json_data),
)
assert rsp.ok, rsp.status_code

Django REST framework 是严格区分PUT和PATCH的,这一点和flask-restless 不一样,需要注意。

总结

以上所述是小编给大家介绍的使用python为mysql实现restful接口,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
python网络编程学习笔记(四):域名系统
Jun 09 Python
python文件和目录操作函数小结
Jul 11 Python
玩转python爬虫之URLError异常处理
Feb 17 Python
详解python中字典的循环遍历的两种方式
Feb 07 Python
python实现上传下载文件功能
Nov 19 Python
python 中的divmod数字处理函数浅析
Oct 17 Python
分享6个隐藏的python功能
Dec 07 Python
python实现读取大文件并逐行写入另外一个文件
Apr 19 Python
python3将视频流保存为本地视频文件
Jun 20 Python
利用selenium爬虫抓取数据的基础教程
Jun 10 Python
django中使用事务及接入支付宝支付功能
Sep 15 Python
python 用opencv实现霍夫线变换
Nov 27 Python
微信跳一跳python代码实现
Jan 05 #Python
python+opencv轮廓检测代码解析
Jan 05 #Python
python selenium UI自动化解决验证码的4种方法
Jan 05 #Python
轻松实现TensorFlow微信跳一跳的AI
Jan 05 #Python
OpenCV-Python实现轮廓检测实例分析
Jan 05 #Python
django2 快速安装指南分享
Jan 05 #Python
Python实现改变与矩形橡胶的线条的颜色代码示例
Jan 05 #Python
You might like
用PHP实现多服务器共享SESSION数据的方法
2007/03/16 PHP
php采集速度探究总结(原创)
2008/04/18 PHP
Discuz 模板引擎的封装类代码
2008/07/18 PHP
用PHP书写安全的脚本代码
2012/02/05 PHP
深入浅析用PHP实现MVC
2016/03/02 PHP
基于Laravel5.4实现多字段登录功能方法示例
2017/08/11 PHP
PHP解析url并得到url参数方法总结
2018/10/11 PHP
js cookies 常见网页木马挂马代码 24小时只加载一次
2009/04/13 Javascript
Jquery操作下拉框(DropDownList)实现取值赋值
2013/08/13 Javascript
jQuery实现控制文字内容溢出用省略号(…)表示的方法
2016/02/26 Javascript
jQuery前端开发35个小技巧
2016/05/24 Javascript
AngularJS实现动态编译添加到dom中的方法
2016/11/04 Javascript
JS设置时间无效问题的解决办法
2017/02/18 Javascript
vue 解决addRoutes动态添加路由后刷新失效问题
2018/07/02 Javascript
Vue使用lodop实现打印小结
2019/07/06 Javascript
Elasticsearch实现复合查询高亮结果功能
2019/09/10 Javascript
extjs图表绘制之条形图实现方法分析
2020/03/06 Javascript
通过vue刷新左侧菜单栏操作
2020/08/06 Javascript
[46:00]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第一局
2016/03/03 DOTA
[01:03:36]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第二场 1月26日
2021/03/11 DOTA
对python .txt文件读取及数据处理方法总结
2018/04/23 Python
django初始化数据库的实例
2018/05/27 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
2019/03/18 Python
用python按照图像灰度值统计并筛选图片的操作(PIL,shutil,os)
2020/06/04 Python
详解Html5原生拖拽操作
2018/01/12 HTML / CSS
很酷的小工具和电子产品商城:GearBest
2016/11/19 全球购物
汇集了世界上最好的天然和有机美容产品:LoveLula
2018/02/05 全球购物
世界上最值得信赖的多日游在线市场:TourRadar
2018/07/20 全球购物
马来西亚太阳镜、眼镜和隐形眼镜网上商店:Focus Point
2018/12/13 全球购物
Madewell澳大利亚官方网站:美国休闲服饰品牌
2019/07/18 全球购物
元旦活动感言
2014/03/08 职场文书
爱护公物演讲稿
2014/09/09 职场文书
就业协议书怎么填
2014/09/15 职场文书
vue2实现provide inject传递响应式
2021/05/21 Vue.js
MySQL大小写敏感的注意事项
2021/05/24 MySQL
利用Python实现Picgo图床工具
2021/11/23 Python