zoukankan      html  css  js  c++  java
  • SQLAlchemy+Flask-RESTful使用(二)

    前言

    本来没想到能这么快出二的,谁知道序列化组件写上头了.分享知识真的会上瘾....

    变更记录

    # 19.3.18 起笔

    # 19.3.18 使用SQLAlchemy排序方法

    # 19.3.18 补充RESTful时接收参数(POST)

    # 19.3.21 补充多个路由匹配同一个view

    # 19.3.21 补充SQLAlchemy的OR和AND查询

    # 19.4.15 将POST传参修改为传参

    正文

    SQLAlchemy排序

    该排序目前在 百度 上的内容多半是 .order_by('字段') 或 .order_by('-字段')的方式,前一个是正序,后一个是倒序

    但是实际运行中虽然可以正常跑起来但是会出现提示

    C:UsersAdministratorAppDataLocalProgramsPythonPython37libsite-packagessqlalchemysqlcompiler.py:763: SAWarning: Can't resolve label reference 'vip_order.found_time'; converting to text() (this warning may be suppressed after 1ler.py:763: SAWarning: Can't resolve label reference 'vip_order.found_time'; converting to text() (tng may behis warning may be suppressed after 10 occurrences)
      util.ellipses_string(element.element),

    大概就是 SQLAlchemy 组件认不出来但是语法 mysql 可以认出来,所以给个警告.

     打印了一下执行的sql,明白了order_by的方式实际上就是在 sql 语句后拼接

    order by 括号内内容

    那么,正确的排序(不出提示)应该是怎样的呢

    .order_by(desc('字段'))  # 倒序
    .order_by('字段')  # 正序

    要注意的是在倒序时需要先引入 desc

    from sqlalchemy import desc

    接收参数

    以POST为例

    我觉得POST是使用最频繁的提交方法了.之前也看有人说把其他所有请求砍掉只保留POST也可以开发API

    RESTFul的POST参数接收比较复杂,但是有友好的错误提示,多一点代码提高前后端交流的速度.会到就是爽到

    不说废话,来看demo

            parser = reqparse.RequestParser()  # 生成parser
            parser.add_argument('name', type=int, help='name error', required=True)  # 获取name字段,type指类型,help为定义错误时的提示(不写有默认的),required默认False(没接收到默认为None)/True为不传返回错误信息(help)
            parser.add_argument('pwd', type=str, help='pwd error', required=True)  # pwd字段,同上
            args = parser.parse_args(strict=True)  # 获取传输的值/strict=True代表设置如果传以上未指定的参数主动报错
            name = args['name']  # 获取用户名字
            pwd = args['pwd']  # 获取用户密码(前端加密)

    解释一下,首先必须要生成parser

    然后 add_argument 方法相当于最外层的一个保险,我们之前提到的 友好的错误提示 就在这里生效

    来看第二行,第二行是校验 POST提交中 body里的一个key叫 name 的字段,

    type意思是restful会简单校验一下 key 的 v 的值,不写type代表不校验

    help意思是restful在任何不匹配的情况下都会返回help的值,如果不定义也有默认值(推荐不写help,因为自带的错误提示多变且更加友好)

    以下为例子

    第三个参数 required 如果为False(默认)代表如果用户没有传则为None / 为True代表不传直接报错(同上)

    args = parser.parse_args(strict=True)

    这行代表是否启用严格模式,True 代表严格模式启动,如果传入不在上面规定的参数则会报错

    Flask-RESTful设置多个路由指向统一的view

    有时候我们希望匹配的多个路由进入一个函数/类处理,比如 访问用户的url 我们可以GET时带上id获取该用户信息,也希望POST时不带id代表新增用户

    那么,如果按照之前的方法,启动 Flask 时会报错

    api.add_resource(Vip, '/website/vip/<int:vip_id>')  # 获取VIP常用信息(匹配url带有int数字的传给Vip视图,url的参数命名为vip_id)
    api.add_resource(Vip, '/website/vip')  # 新建用户

    抛出

    AssertionError: View function mapping is overwriting an existing endpoint function: website_1_0.vip

    这是因为 Flask-RESTful 内部有一个 endpoint 作为每个路由匹配的view的代号,如果你不写则默认为你的 view 的名字

    所以在启动时检测到了两个名为 vip 的代号,所以会报错

    解决办法是每次写 路由 时带上endpoint同时保证唯一

    api.add_resource(Vip, '/website/vip/<int:vip_id>', endpoint='Vip')  # 获取VIP常用信息(匹配url带有int数字的传给Vip视图,url的参数命名为vip_id)
    api.add_resource(Vip, '/website/vip', endpoint='Vips')  # 新建用户

    SQLAlchemy OR 查询

    假设有一个需求是在新用户注册时判断邮箱和昵称是否重复,重复则拦截.我们有两种方法

    一:建表设置唯一,然后插入数据时捕捉异常

    这种方法也是可行的.但是本人认为最好不要等着数据库报错,所以此方法这里不谈

    二:先查询是否有该用户,有则报错

    这里介绍方法二

    值得注意的是,这里的邮箱和昵称是两张表的字段,而且需求是 name 或 email 重复则报错,这里就用到 OR 查询

    Vip_obj = session.query(Vip).join(VipInfo).filter((Vip.name==name)|(VipInfo.email==email)).first()

    我们在filter时将多个判断用 | 接起来即可

    SQLAlchemy AND 查询

    就拿 OR 查询举例子 AND和 OR 差不多

    Vip_obj = session.query(Vip).join(VipInfo).filter(Vip.name==name, VipInfo.email==email).first()

    用 , 链接即可,不带括号

  • 相关阅读:
    Java实现 LeetCode 155 最小栈
    Java实现 LeetCode 155 最小栈
    Java实现 LeetCode 154 寻找旋转排序数组中的最小值 II(二)
    Java实现 LeetCode 154 寻找旋转排序数组中的最小值 II(二)
    Java实现 LeetCode 154 寻找旋转排序数组中的最小值 II(二)
    IsBadStringPtr、IsBadWritePtr
    IPicture、BITMAP、HBITMAP和CBitmap的关系
    DrawDibDraw函数的使用方法
    第二章排错的工具:调试器Windbg(上)
    第二章排错的工具:调试器Windbg(下)
  • 原文地址:https://www.cnblogs.com/chnmig/p/10553587.html
Copyright © 2011-2022 走看看