Flask戰爭之查詢後臺管理接口開發實錄--篩選器

篩選器接口

條件

原始查詢sql
SELECT DATE(rl.created_at) AS `date`,
	path,
	rl.account_id,
	org,
	COUNT(*) AS request_count,
	SUM(IF(rl.`response_status` = 200, 1, 0)) AS success_count,
	SUM(IF(ff.id IS NOT NULL, 1, 0)) AS paid_count,
	COALESCE(JSON_EXTRACT(pricing_config, CONCAT('$.', JSON_QUOTE(path))), '') AS pricing,
	SUM(ff.amount) AS price
FROM `request_log` rl
LEFT JOIN `fund_flow` ff USING(request_id)
LEFT JOIN `pricing` ON pricing_id = pricing.id
#WHERE {filters}
GROUP BY `date`, `path`, rl.`account_id`, `org`
對應sqlachemy語句
# -*- coding:utf-8 -*-
import os
from flasgger import swag_from
from . import admin_server
from flask import request
from apps import db
from .models import RequestLog, FundFlow, Pricing
from sqlalchemy import func
from sqlalchemy.sql import and_

base_dir = os.path.dirname(__file__)
demo_yml_path = os.path.join(base_dir, "docs/admin_server.yml")

class JSONHelper():
	# 將結果轉化爲json格式文本
    @staticmethod
    def jsonBQlist(bqlist):
        result=[]
        for item in bqlist:
            jsondata={}
            for i in range(item.__len__()):
                tdic={item._fields[i]:item[i]}
                jsondata.update(tdic)
            result.append(jsondata)
        return result

@admin_server.route('/count_operator', endpoint="count_operator", methods=['POST'])
# 裝飾器 藍圖 
@swag_from(demo_yml_path, endpoint="admin_server.count_operator", methods=['POST'])
# 裝飾器 文檔
def query_op():
    """
    運營通過篩選器進行查詢
    :param: # 參數
        {
            "date_start": "2019-07-20",
            "date_end": "2019-08-01",
            "org": "", # 機構
            "account_id": [0,1], # 客戶id
            "path": ""  # 產品 後期可能會接收列表
        }
    :return: # 返回值
    {
        "data": {
            "search_res": [
                {
                    "account_id": 0,
                    "date": "2019-07-10 14:10:28",
                    "org": "",
                    "paid_count": "1",
                    "path": "/api/v1/pull/identity",
                    "price": null,
                    "pricing": "",
                    "request_count": 1,
                    "success_count": "0"
                }
            ],
            "total": {
                "paid_count": 1,
                "price": 0,
                "request_count": 1,
                "success_count": 0
            }
        }
    }

    """
    input_json = request.json
    # 通過flask的request來獲取請求接口的輸入參數
    date_start = input_json["date_start"]
    date_end = input_json["date_end"]
    account_id = input_json["account_id"]
    org = input_json["org"]
    path = input_json["path"]
    search_conditions = []
    # 定義搜索條件列表
    if date_start and date_end:
        search = and_(RequestLog.created_at.between(date_start, date_end))
        # and_ sqlachemy 的用法 連接請求的條件
        search_conditions.append(search)
    if account_id:
        search = and_(RequestLog.account_id.in_(account_id))
        search_conditions.append(search)

    if org:
        search = and_(RequestLog.org == org)
        search_conditions.append(search)

    if path:
        search = and_(RequestLog.path == path)
        search_conditions.append(search)

    res_sql = db.session\
        .query(
            RequestLog.created_at.label("date"),
            RequestLog.path,
            RequestLog.account_id,
            RequestLog.org,
            func.count().label("request_count"),
            # sqlachemy 使用統計函數 label 標籤 也就是列名
            func.SUM(func.if_(RequestLog.response_status == 200, 1, 0)).label("success_count"),
            # if_ 如果response_status 狀態爲 200 則值爲1 否則爲0
            func.SUM(func.if_(FundFlow.id is not None, 1, 0)).label("paid_count"),
            func.coalesce(func.json_extract(Pricing.pricing_config, func.concat('$.', func.json_quote(RequestLog.path))), "").label("pricing"),
            # json_quote 將json格式數據轉化爲json格式的字符串
            # json_extract 獲取json字段中的某個key的值
            # concat 字符串拼接
            # coalesce 遇到非null值返回該值,否則返回空
            func.SUM(FundFlow.amount).label("price"),
        ) \
        .outerjoin(FundFlow, RequestLog.request_id == FundFlow.request_id)\
        # outerjoin 相當於sql中的left join
        .outerjoin(Pricing, FundFlow.id == Pricing.id)\
        .filter(*tuple(search_conditions))\
        # * 解構 
        .group_by("date", RequestLog.path, RequestLog.account_id, RequestLog.org)\
        .all()
	# 在這裏拿到的 search_res 是一個查詢的結果集  打印輸出類型<class 'sqlalchemy.util._collections.result'>
	
    search_res = JSONHelper.jsonBQlist(res_sql)
        for index,item in enumerate(search_res):
        item_str = JSONEncoder().encode(item)
        item = json.loads(item_str)
        search_res[index] = item

    success_count = sum([int(k["success_count"]) for k in search_res])
    # 轉化爲整型進行求和運算
    request_count = sum([int(k["request_count"]) for k in search_res])
    paid_count = sum([int(k["paid_count"]) for k in search_res])
    price = sum([int(k["price"]) for k in search_res if k["price"]])

    total = {}
    total["request_count"] = request_count
    total["success_count"] = success_count
    total["paid_count"] = paid_count
    total["price"] = price

    data = {
        "search_res": search_res,
        "total":total
    }

    return {"data":data}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章