开发环境:Web框架:flask
数据库:mysql
驱动: pymysql
ORM: flask_sqlalchemy
客户端:httpie
日志:logging
代码结构:
app.py flask主文件
myconfig.py flask的配置内容
mymodel.py orm的模型类
mydb.py 防止循环引用,在mydb.py中完成flask_sqlalchemy对象的创建
myconfig.py源代码:
DEBUG = True
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:password@localhost:3306/mytest'
SQLALCHEMY_TRACK_MODIFICATIONS = False
DATABASE_QUERY_TIME = 0.0001
SQLALCHEMY_RECORD_QUERIES = True
其中DATABASE_QUERY_TIME使用来演示日志的,时间是随意写的,实际使用时可以根据需要调整。
mymodel.py源码
from mydb import db
class User(db.Model):
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
name = db.Column(db.String(80),unique=True)
mydb.py源码
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
注意,这里创建db的时候构造器中不要传入flask对象,否则一样会引发循环引用
app.py源码:
from flask import Flask,request,jsonify
from flask_sqlalchemy import get_debug_queries
from mydb import db
from mymodel import User
import logging
from logging import FileHandler
app = Flask(__name__)
app.config.from_object('myconfig')
formatter = logging.Formatter('%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
handler = FileHandler('myquery.log')
handler.setFormatter(formatter)
handler.setLevel(logging.WARN)
app.logger.addHandler(handler)
db.init_app(app)
with app.app_context():
db.drop_all()
db.create_all()
@app.route('/users',methods=['POST'])
def users():
uname = request.form.get('name')
u = User(name = uname)
db.session.add(u)
db.session.commit()
return jsonify({'id':u.id})
@app.after_request
def after_request(resp):
for q in get_debug_queries():
if q.duration >= app.config['DATABASE_QUERY_TIME']:
app.logger.warn('CONTEXT:{}\n SLOW QUERY:{} \n PARAMETERS:{}\n DURATION: {}\n'.format(
q.context,q.statement,q.parameters,q.duration
))
return resp
注意,一些重要代码的解读:
app.config.from_object('myconfig'):从myconfig中读取配置信息,不用再写app.config['XXX']=xxx了。
db.init_app(app): 在mydb.py中没有传入app对象是为了防止循环引用,现在需要完成对db的初始化。
with app.app_context():执行drop_all和create_all操作时需要使用到应用上下文的内容,使用app_context就是提供应用上下文。
@app.after_request:在请求结束响应送回客户端之前,被修饰的钩子方法会被调用。我们在这里进入日志的记录。通过app.logger.warn产生一条WARN级别的日志信息(message)
代码完成后,利用命令行启动flask服务器:
flask run -h 0.0.0.0 -p 9090
利用第三方工具httpie(官网:https://httpie.org/)发起请求:
http -f post localhost:9090/users name=tom
以post方式向localhost:9090/users发起一个请求,携带的是表格形式的参数,内容为name=tom
当请求到达服务器后,会以tom为name创建一条数据记录写入到mytest数据库的user表中。同时返回json字符串{'id':1}作为响应。