SQLAlchemy+Flask-RESTful使用(三)
前言
顺理成章地,19.3.21起笔了第三章.也就是最近没啥事了,才有时间搞这些.生命不息奋斗不止吧!
变更记录
# 19.3.21 起笔
# 19.3.21 增加 Flask-RESTful如何获取body/args/header的值
# 19.4.3 增加 使用sqlalchemy-utils达到类似Django的choices(插入/更新值时限制值)效果
# 19.4.10 增加 建立model时指定排序
# 19.4.12 增加 解决多个model文件使用同一个Base的问题
正文
Flask-RESTful获取body/args/header的值
百度一番没啥思路,最后还是看的官方文档(以下内容取至官方文档+Google翻译)
参数位置
默认下,
RequestParser试着从flask.Request.values,以及flask.Request.json解析值。在
add_argument()中使用location参数可以指定解析参数的位置。flask.Request中任何变量都能被使用。例如:# Look only in the POST body
parser.add_argument('name', type=int, location='form') # Look only in the querystring
parser.add_argument('PageSize', type=int, location='args') # From the request headers
parser.add_argument('User-Agent', type=str, location='headers') # From http cookies
parser.add_argument('session_id', type=str, location='cookies') # From file uploads
parser.add_argument('picture', type=werkzeug.datastructures.FileStorage, location='files')
我们可以看到,官方文档指出,从特定位置取数据只需要在 add_argument 里指定 location 即可
不指定 location 的话默认从args和form中取(写在header中无法取到)
如果取不到理所当然的报错啦,这里给一个例子
parser.add_argument('token', type=str, help='token error', required=True, location='headers') # 从headers中获取token
以上代码就达成了从headers中获取token的作用,没有token则会返回 tokenerror
sqlalchemy-utils达到类似Django的choices效果
首先要注明的是这个限制并不是限制在数据库中的,因此不经过ORM的数据不受限制
首先安装模块
pip install sqlalchemy-utils
sqlalchemy-utils 模块有很多功能,choices功能只是其中一个,但是网上该模块的使用比较稀少.
这里只介绍这一个功能
官方文档
https://sqlalchemy-utils.readthedocs.io/en/latest/
使用DEMO
from sqlalchemy.orm import sessionmaker, relationship, backref
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String, Integer, ForeignKey, DateTime
from sqlalchemy_utils import ChoiceType class User(mysql_Base):
# 用户表
__tablename__ = 'user' # 表名
lv_choices = (
(1, 'vip1'),
(2, 'vip2')
)
id = Column(Integer, primary_key=True) # 主键
name = Column(String(15), nullable=False, index=True, unique=True) # 用户名,不为空,唯一
pwd = Column(String(20), nullable=False) # 密码,不为空
lv = Column(ChoiceType(lv_choices, Integer()))
建立model时指定查询数据时排序
在正常业务中,我们通常会遇到按照某个字段进行排序的需求,在SQLAlchemy中我们既可以在查询时使用 orderby 方式查询
也可以在建立model时指定默认排序
demo如下
class Commodity(mysql_Base):
# 商品表(非H5)
__tablename__ = 'commodity' # 表名
delete_choices = (
(0, '未删除'),
(1, '已删除')
)
id = Column(BigInteger, primary_key=True) # 主键
name = Column(String(25), nullable=False, unique=True) # 商品名称,不可为空,唯一
introduce = Column(Text) # 商品详细说明(可为空)
note = Column(String(256)) # 商品备注(后台,可为空)
title_img = Column(String(256)) # 大图链接(可为空)
integral = Column(Integer, nullable=False, default=0) # 商品价格(不为空/默认0)
vaild_day = Column(Integer, nullable=False, default=30) # 商品有效时间(天/不为空/默认30)
repertory = Column(Integer, nullable=False, default=10000) # 商品库存(不为空/默认1w)
# putaway_time = Column(DateTime, nullable=False) # 商品上架时间(不为空)
# soldout_time = Column(DateTime, nullable=True) # 商品下架时间(为空代表无限制)
create_time = Column(DateTime, nullable=False) # 商品添加时间(不为空)
update_time = Column(DateTime, nullable=False) # 商品最后更新时间(不为空)
delete = Column(ChoiceType(delete_choices, Integer)) # 删除状态
# 指定默认排序为update_time
__mapper_args__ = {
'order_by': update_time.desc()
}
这种方法有利有弊,利是以后输出无需再写排序/弊是不够灵活(比如我们要求排序先把delete为1的去掉再排序)
所以怎么使用还是要看业务需求
多个model文件使用一个Base
一般情况下,我们的业务表结构比较复杂,一个model文件不利于后期的迭代和维护
关于Flask的文件夹配置是没有标准的,Flask的核心成员之一在 lepture 回答了该问题,他指出目录结构应该是灵活的.舒服就好
这里是我常用的文件结构

言归正传
我们虽然可以一个model中创建一个 Base, 但是会出现问题,在使用 alembic 提交数据库的时候,如果我在 modelA中创建表a ,在 modelB中创建表b并有一个字段关联表a
会报错,大致翻译是没有找到表a的id
解决方法是所有model使用同一个Base
首先我们在 config 配置文件中直接建立一个Base
# 用户名:密码@访问地址:端口/数据库
mysql_engine = create_engine('mysql+mysqldb://root:***@***:***/boom_web?charset=utf8mb4',
pool_recycle=7200, # 空闲时间后自动关闭
pool_size=20, # 最大连接数
pool_timeout=30, # 连接超时
echo=False # 输出每次执行的sql
) # 创建Base基类
mysql_Base = declarative_base()
然后我们将 env 中的配置文件改为
from config.config import mysql_Base
# target_metadata = [user_db.metadata, commodity_db.metadata, workorder_db.metadata] # 多个Base可用列表方式全部写进去,[bs1.metadata, bs2.metadata, ...]
target_metadata = [mysql_Base.metadata]
# 注意引入的时候要注意直接import到Base,多一级比如 config.mysql_Base 也会报错
然后我们在所有model中引入
from config.config import mysql_Base
class User(mysql_Base):
pass
然后写完一个model记得将表引入到 config 中
在config的下方加到
(不加会导致检测不到model)
from app.commodity.models import *
from app.user.models import *
from app.workorder.models import *
完整 config 为
# -*- coding=utf-8 -*- from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import sessionmaker, relationship, backref
from sqlalchemy.ext.declarative import declarative_base # 用户名:密码@访问地址:端口/数据库
mysql_engine = create_engine('mysql+mysqldb://root:***@***:***/boom_web?charset=utf8mb4',
pool_recycle=7200, # 空闲时间后自动关闭
pool_size=20, # 最大连接数
pool_timeout=30, # 连接超时
echo=False # 输出每次执行的sql
) # 创建Base基类
mysql_Base = declarative_base() # 创建DBSession类型
mysql_DBSession = sessionmaker(bind=mysql_engine) from app.commodity.models import *
from app.user.models import *
from app.workorder.models import *
这样再执行提交即可
SQLAlchemy+Flask-RESTful使用(三)的更多相关文章
- Python Flask Restful
Flask Restful 1.flask restful 在flask基础上进行一些封装,主要用于实现restful接口 2.restful的理解 1)URI(统一资源标识符):每一个URI代表一 ...
- Springboot & Mybatis 构建restful 服务三
Springboot & Mybatis 构建restful 服务三 1 前置条件 成功执行完Springboot & Mybatis 构建restful 服务二 2 restful ...
- 使用swagger 生成 Flask RESTful API
使用swagger 生成 Flask RESTful API http://www.voidcn.com/article/p-rcvzjvpf-e.html swagger官网 https://swa ...
- Flask 学习(三)模板
Flask 学习(三)模板 Flask 为你配置 Jinja2 模板引擎.使用 render_template() 方法可以渲染模板,只需提供模板名称和需要作为参数传递给模板的变量就可简单执行. 至于 ...
- Flask restful源码分析
Flask restful的代码量不大,功能比较简单 参见 http://note.youdao.com/noteshare?id=4ef343068763a56a10a2ada59a019484
- Flask框架(三)—— 请求扩展、中间件、蓝图、session源码分析
Flask框架(三)—— 请求扩展.中间件.蓝图.session源码分析 目录 请求扩展.中间件.蓝图.session源码分析 一.请求扩展 1.before_request 2.after_requ ...
- 如何用rflask快速初始化Flask Restful项目
如何用rflask快速初始化Flask Restful项目 说明 多啰嗦两句 我们在创建flask项目的时候,使用pycharm创建出来的项目比较简陋,而且随着项目的功能完善,项目目录结构会比较多,多 ...
- [flask]Restful接口测试简单的应用
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Author : shenqiang from flask import Flask,make_res ...
- 快速创建Flask Restful API项目
前言 Python必学的两大web框架之一Flask,俗称微框架.它只需要一个文件,几行代码就可以完成一个简单的http请求服务. 但是我们需要用flask来提供中型甚至大型web restful a ...
- Flask RESTful API搭建笔记
之前半年时间,来到项目的时候,已经有一些东西,大致就是IIS+MYSQL+PHP. 所以接着做,修修补补,Android/iOS与服务器数据库交换用PHP, Web那边则是JS+PHP,也没有前后端之 ...
随机推荐
- POJ 2411 Mondriaan's Dream -- 状压DP
题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...
- JS学习笔记:(一)浏览器页面渲染机制
浏览器的内核主要分为渲染引擎和JS引擎.目前市面上常见的浏览器内核可以分为这四种:Trident(IE).Gecko(火狐).Blink(Chrome.Opera).Webkit(Safari).这里 ...
- 浅析Java数据类型
前言: 该系列会辅以MindMap进行说明. 下面会贴两张我不同时期画的Java数据类型的思维导图,本篇主要侧重于Java的8种基本类型 MindMap-1 这张MindMap主要是根据 菜鸟教程+参 ...
- Ubuntu 16.04 安装opencv3.4.5/cuda/caffe并使用jni笔记
因操作失误,误卸开发机NVIDIA显卡驱动,先更新操作日志如下: 1>NVIDIA驱动重装 1.卸载系统里的Nvidia残余 sudo apt-get purge nvidia* 2.把显卡驱动 ...
- Linux-系统调用理解
系统调用即为Linux内核中设置的一组用于实现各种系统功能的子程序,操作系统通过系统调用为运行在其上的进程提供服务. 由于进程一般不能访问内核所占内存空间以及调用内核函数,为了与用户态进程进行交互,内 ...
- Mac下查看已安装的jdk版本及其安装目录
1.打开终端,输入:/usr/libexec/java_home -V 注意:输入命令参数区分大小写(-v是不对的,必须是-V) 2.如图:为输入命令: 当前Mac已安装jdk目录: Mac默认使用的 ...
- VS配置Halcon(一次配置,永久使用)
[说明]只需配置一次,以后新项目无需再次配置. 本教程是64位版本,32位可参考本教程.VS与Halcon无论哪个版本,都可参考本教程. [步骤]以VS2015+Halcon18.11为例 1.新建一 ...
- CTF--web
https://adworld.xctf.org.cn/task/task_list?type=web&number=3&grade=0 1.view source 查看源代码 1.鼠 ...
- Jira与Confluence集成、授权信息查看和问题汇总
上一篇文章详细阐述了jira和confluence的安装部署和相关配置的操作记录,也介绍了两者之间其中一种集成方式:下面介绍另外的集成方式. 安装部署jira和confluence的顺序是,先安装ji ...
- postman接口测试笔记
1.GET 和POST 的区别: GET 使用URL 或Cookie 传参,而POST将数据放在Body 中. GET的URL 在长度上会有限制,而POST没有. POST比GET相对安全,因为在地址 ...