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:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\sql\compiler.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()

用 , 鏈接即可,不帶括號

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM