当前位置:首页>python>从数据可视化到AI应用开发:Python全栈实战之旅

从数据可视化到AI应用开发:Python全栈实战之旅

  • 2026-08-18 23:10:27
从数据可视化到AI应用开发:Python全栈实战之旅

前言

在当今的技术世界中,Python以其简洁优雅的语法和强大的生态系统,成为了数据科学和Web开发领域的中流砥柱。作为一名Python开发者,你是否曾经想过:如何将数据分析的能力与Web应用开发相结合,打造出既有数据洞察力又具备交互性的智能应用?

本文将带你完成一场从数据分析可视化到AI智能应用开发的完整技术之旅。我们将从TMDB-TOP300电影榜单的数据分析入手,逐步深入到使用FastAPI构建"汉字迷盒"——一个基于DeepSeek大语言模型的智能字谜互动游戏。


数据分析案例

  1. 准备工作:导入依赖库、配置运行时参数、创建子图完成基本布局、加载数据
  2. 统计TOP300的电影中,每一年上映的电影数量的变化。(折线图)
  3. 统计对比不同语言电影数量。(柱状图)
  4. 统计对比不同类型电影数量。(柱状图)
  5. 统计对比各个电影评分的比例。(饼状图)

准备工作

import pandas as pdimport matplotlib.pyplot as pltfrom matplotlib.axes import Axes#展示中文plt.rcParams['font.sans-serif'] = ['SimHei']# 创建子图fig,axes = plt.subplots(nrows=2,ncols=2,figsize=(20,12),dpi = 100)fig.suptitle('TMDB-TOP300电影榜单数据统计',fontsize=23,x=0.5,y=0.95)#获取子图axes1:Axes = axes[0][0]axes2:Axes = axes[0][1]axes3:Axes = axes[1][0]axes4:Axes = axes[1][1]#加载数据data = pd.read_csv('../data/movies.csv',usecols=['电影名','年份','上映时间','类型','时长','评分','语言'],dtype={'年份':'Int64'})
① 创建一个 2×2 的画布            │            ▼② 给整个画布添加标题            │            ▼③ 将四个子图分别命名为   axes1、axes2、axes3、axes4            │            ▼④ 从 movies.csv 中读取需要的电影数据            │            ▼⑤ 后续可分别在四个子图中绘制不同统计图   (柱状图、折线图、饼图、散点图等)

统计TOP300的电影中,每一年上映的电影数量的变化。(折线图)

# 统计TOP300的电影中,每一年上映的电影数量的变化。(折线图)# 缺失值、异常值处理data['年份'] = data['年份'].fillna(data['上映时间'].str[:4])#分组统计yeart_count =  data.groupby('年份')['年份'].count()# 组装数据# x轴数据min_yaer = yeart_count.index.min()max_year = yeart_count.index.max()x = [ i for i in range(min_yaer,max_year + 1)]# y轴数据y = [int(yeart_count.get(i, 0)) for i in x]# 绘制折线图axes1.plot(x,y,color='green')axes1.set_title("每年电影数量变化折线图",fontsize=18)axes1.set_xlabel('年份',fontsize=12)axes1.set_ylabel('电影数量',fontsize=12)axes1.set_xticks(x[::8]) # x轴刻度y_ticks = [i for i in range(0,31,3)]axes1.set_yticks(y_ticks) # y轴刻度axes1.grid(linestyle='--',alpha=0.5# 网格线

fillna() 作用:用指定的数据填充空值(NaN) 如果"年份"为空,就使用"上映时间"中的年份补充。 统计对比不同语言电影数量。(柱状图)

# 不同语言的电影数量language_count = data.groupby('语言')['语言'].count().sort_values(ascending=False)x_lanuage = language_count.index.tolist()y_lanuage = language_count.values.tolist()#绘制柱装图axes2.bar(x_lanuage,y_lanuage,color='green',width=0.7#柱状图axes2.set_title("不同语言的电影数量",fontsize=18)axes2.set_xlabel('语言',fontsize=12# x轴标签axes2.set_ylabel('电影数量',fontsize=12# y轴标签axes2.grid(linestyle='--',alpha=0.5# 网格线axes2.tick_params(axis='x', rotation=45# x轴标签旋转

 统计对比不同类型电影数量。(柱状图)

# 统计对比不同类型电影数量。(柱状图)type_count = {}for types in data['类型'].str.split(','):    for type in types:        if type in type_count:            type_count[type] += 1        else:            type_count[type] = 1x_types = list(type_count.keys())y_types = list(type_count.values())#绘制柱装图axes3.bar(x_types,y_types,color='green',width=0.7#柱状图axes3.set_title("不同类型的电影数量",fontsize=18)axes3.set_xlabel('类型',fontsize=12# x轴标签axes3.set_ylabel('电影数量',fontsize=12# y轴标签axes3.grid(linestyle='--',alpha=0.5# 网格线axes3.tick_params(axis='x', rotation=45# x轴标签旋转

 统计对比各个电影评分的比例。(饼状图)

# 统计对比各个电影评分的比例score_count =  data.groupby('评分')['评分'].count()scores = score_count.index.tolist()scores_values = score_count.values.tolist()# 合并小数据(比例小于2%) --> 其他total = score_count.sum()large_scores = score_count.loc[score_count >= total * 0.02] #大数据small_scores = score_count.loc[score_count < total * 0.02] #小数据if small_scores.shape[0] > 0:    other_count = small_scores.sum()    large_scores['其他'] = other_count# 绘制饼状图axes4.pie(large_scores, labels=large_scores.index, autopct='%1.1f%%', startangle=0,radius=1.2) # startangle 起始角度axes4.set_title("不同评分的电影数量占比比例",fontsize=18)axes4.legend(loc='lower center',ncol=4,bbox_to_anchor=(0.5,-0.19))

loc 是 Pandas 中基于标签(label)的索引器,用于通过行标签和列标签来获取数据。 loc 根据布尔条件的 True/False 来筛选数据:

  • True:保留该行数据
  • False:过滤掉该行数据

完整代码

import pandas as pdimport matplotlib.pyplot as pltfrom matplotlib.axes import Axes#展示中文plt.rcParams['font.sans-serif'] = ['SimHei']# 创建子图fig,axes = plt.subplots(nrows=2,ncols=2,figsize=(20,12),dpi = 100)fig.suptitle('TMDB-TOP300电影榜单数据统计',fontsize=23,x=0.5,y=0.95)plt.subplots_adjust(hspace=0.35, wspace=0.3)#获取子图axes1:Axes = axes[0][0]axes2:Axes = axes[0][1]axes3:Axes = axes[1][0]axes4:Axes = axes[1][1]#加载数据data = pd.read_csv('../data/movies.csv',usecols=['电影名','年份','上映时间','类型','时长','评分','语言'],dtype={'年份':'Int64'})# 统计TOP300的电影中,每一年上映的电影数量的变化。(折线图)# 缺失值、异常值处理data['年份'] = data['年份'].fillna(data['上映时间'].str[:4])#分组统计yeart_count =  data.groupby('年份')['年份'].count()# 组装数据# x轴数据min_yaer = yeart_count.index.min()max_year = yeart_count.index.max()x = [ i for i in range(min_yaer,max_year + 1)]# y轴数据y = [int(yeart_count.get(i, 0)) for i in x]# 绘制折线图axes1.plot(x,y,color='green')axes1.set_title("每年电影数量变化折线图",fontsize=18)axes1.set_xlabel('年份',fontsize=12)axes1.set_ylabel('电影数量',fontsize=12)axes1.set_xticks(x[::8]) # x轴刻度y_ticks = [i for i in range(0,31,3)]axes1.set_yticks(y_ticks) # y轴刻度axes1.grid(linestyle='--',alpha=0.5# 网格线# 不同语言的电影数量language_count = data.groupby('语言')['语言'].count().sort_values(ascending=False)x_lanuage = language_count.index.tolist()y_lanuage = language_count.values.tolist()#绘制柱装图axes2.bar(x_lanuage,y_lanuage,color='green',width=0.7#柱状图axes2.set_title("不同语言的电影数量",fontsize=18)axes2.set_xlabel('语言',fontsize=12# x轴标签axes2.set_ylabel('电影数量',fontsize=12# y轴标签axes2.grid(linestyle='--',alpha=0.5# 网格线axes2.tick_params(axis='x', rotation=45# x轴标签旋转# 统计对比不同类型电影数量。(柱状图)type_count = {}for types in data['类型'].str.split(','):    for type in types:        if type in type_count:            type_count[type] += 1        else:            type_count[type] = 1x_types = list(type_count.keys())y_types = list(type_count.values())#绘制柱装图axes3.bar(x_types,y_types,color='green',width=0.7#柱状图axes3.set_title("不同类型的电影数量",fontsize=18)axes3.set_xlabel('类型',fontsize=12# x轴标签axes3.set_ylabel('电影数量',fontsize=12# y轴标签axes3.grid(linestyle='--',alpha=0.5# 网格线axes3.tick_params(axis='x', rotation=45# x轴标签旋转# 统计对比各个电影评分的比例score_count =  data.groupby('评分')['评分'].count()scores = score_count.index.tolist()scores_values = score_count.values.tolist()# 合并小数据(比例小于2%) --> 其他total = score_count.sum()large_scores = score_count.loc[score_count >= total * 0.02#大数据small_scores = score_count.loc[score_count < total * 0.02#小数据if small_scores.shape[0] > 0:    other_count = small_scores.sum()    large_scores['其他'] = other_count# 绘制饼状图axes4.pie(large_scores, labels=large_scores.index, autopct='%1.1f%%', startangle=0,radius=1.2# startangle 起始角度axes4.set_title("不同评分的电影数量占比比例",fontsize=18)axes4.legend(loc='lower center',ncol=4,bbox_to_anchor=(0.5,-0.19))# 保存图片plt.savefig("../data/TMDB-TOP300.png")plt.show()

FastAPI 基础

Web初识

Web网站由三个核心部分组成:前端程序、服务端程序、数据库。 前端程序:负责前端页面的展示,网页由 HTML(负责网页的结构)、CSS(负责网页的表现)、JavaScript(负责网页的动作) 三个部分组成 。 服务端程序:可以基于Python中的Django、Flask 或 FastAPI来进行开发。

FastAPI入门

FastAPI是一个现代、快速、高性能的Web框架,用于基于标准的Python类型提示构建API接口服务。 官网:https://fastapi.org.cn

API接口:应用程序编程接口(Application Programming Interface),就是对外提供的功能入口,供别人来调用(比如:天气查询的API接口)。

导入FastAPI

from fastapi import FastAPI

创建FastAPI实例对象

app = FastAPI()

创建路径操作函数,定义访问路径

# 定义功能接口@app.get("/")def root():    return {"message""Hello World"}@app.get("/user")def get_user():    return {"user""ZhangSan",            "age"18            }

运行FastAPI服务

# 启动FastAPI服务器if __name__ == "__main__":    import uvicorn    uvicorn.run(app, host="0.0.0.0", port=8000)
fastapi dev "xxxx.py"uvicorn xxxx:app --reload

汉字迷盒案例

开发规范

Restful指的是遵循REST架构风格的API接口服务,而REST(REpresentational State Transfer),表述性状态转换,它是一种软件架构风格。 Restful指的是遵循REST架构风格的API接口服务,而REST(REpresentational State Transfer),表述性状态转换,它是一种软件架构风格。

注意:REST是风格,是约定方式,约定不是规定,可以打破 。 注意:描述功能模块通常使用复数形式(加s),表示此类资源,而非单个资源。如:users、books、items 。

基础环境准备

 汉字谜盒 是一款基于人工智能的字谜互动游戏,专为汉字爱好者设计。在这里,你将与AI机器人进行有趣的猜字挑战! AI会随机出一道经典字谜(如"一箭穿心"),你需要根据谜面提示猜出对应的汉字,AI会根据你的回答给出相应的提示,并给出最终的答案。

from fastapi import FastAPIfrom starlette.responses import FileResponsefrom fastapi.staticfiles import StaticFilesapp = FastAPI(title="汉字迷盒")# 挂载静态文件的存放目录app.mount("/static",StaticFiles(directory="static"),name="static")#定义路径操作函数@app.get('/')def root():    print("访问项目首页")    return FileResponse('static/index.html')if __name__ == '__main__':    import uvicorn    uvicorn.run(app,host='127.0.0.1',port=8000)

挂载静态文件 将static文件夹映射到URL路径/static 参数说明:

  • “/static”:URL访问路径
  • directory=“static”:本地文件夹名称
  • name=“static”:路由名称标识

效果:访问http://127.0.0.1:8000/static/xxx.css就能获取static/xxx.css文件

新建会话

在打开该项目页面时,如果之前没有会话,则要自动创建一个会话,会话标识形式如 2026-04-15_12-00-05。

# 新建会话@app.post("/api/sessions")def create_session():    print("新建会话")    # 生成会话标识    session_id = generate_session_id()    # 组装会话信息,保存到文件中    session_data = {        'current_session': session_id,        'messages': []    }    with open(os.path.join("sessions", session_id + ".json"), "w", encoding="utf-8"as f:        json.dump(session_data, f, ensure_ascii=False, indent=4)    # 返回数据    return {        'code'200,        'message''会话创建成功',        'data': session_id    }
# 数据模型class ApiResponse(BaseModel):    code: int    message: str    data: Any  # 任意类型数据# 新建会话@app.post("/api/sessions")def create_session():    print("新建会话")    # 生成会话标识    session_id = generate_session_id()    # 组装会话信息,保存到文件中    session_data = {        'current_session': session_id,        'messages': []    }    with open(os.path.join("sessions", session_id + ".json"), "w", encoding="utf-8"as f:        json.dump(session_data, f, ensure_ascii=False, indent=4)    # 返回数据    return ApiResponse(code=200, message="会话创建成功", data=session_id)

与AI交互

在会话页面,我们就可以输入我们的问题或者答案,然后请求服务端与AI进行交互了。 在与AI进行交互式,前端传递给服务端的参数包含两项,分别为session_id 与 message,并以json格式在请求体中传递到服务端。

BaseModel:是Pydantic库提供的父类(FastAPI 深度集成了 Pydantic),用于定义FastAPI数据模型和数据验证规则。

class ChatRequest(BaseModel):    session_id: str    message: str# 与Ai交互@app.post("/api/chat")def chat(request: ChatRequest):    print(f"与AI交互:{request.session_id} : {request.message}")    return ApiResponse.success(message='OK',data="AI大模型返回的数据")

在会话页面,我们就可以输入我们的问题或者答案,然后请求服务端与AI进行交互了。

# 与Ai交互client = OpenAI(    api_key="xxxx",    base_url="https://api.deepseek.com")#根据session_id 获取文件名def get_session_file(session_id: str):    return os.path.join("sessions", session_id + ".json")@app.post("/api/chat")def chat(request: ChatRequest):    print(f"与AI交互:{request.session_id} : {request.message}")    # 逻辑实现    # 1.加载json文件中的会话数据    session_file = get_session_file(request.session_id)    with open(session_file, "r", encoding="utf-8"as f:        session_data = json.load(f)    # 2. 构建Ai大模型交互的数据信息    messages = [{'role''system''content': SYSTEM_PROMPT}]    for message in session_data['messages']:        messages.append(message)    messages.append({'role''user''content': request.message})    # 3. 调用AI大模型 deepseek    response = client.chat.completions.create(        model="deepseek-chat",        messages=messages,        stream=False,        temperature=1.5,    )    # 4.获取响应数据    ai_response = response.choices[0].message.content    # 5.更新消息列表中的消息    messages.append({'role''assistant''content': ai_response})    session_data['messages'] = messages    # 6.保存会话信息到json文件中    with open(session_file, "w", encoding="utf-8"as f:        json.dump(session_data, f, ensure_ascii=False, indent=4)    # 7.返回数据    return ApiResponse.success(message='OK',data=ai_response)

会话列表

在汉字谜盒项目的左侧侧边栏,要查询并展示出所有的会话信息,将会话名展示在左侧, 并且根据时间倒序排序。

@app.get('/api/sessions')def get_sessions():    print("获取会话列表")    # 获取sessions文件夹下的所有目录名    session_files = os.listdir("sessions")    # 获取文件名中的会话Id    session_ids = [file.split('.')[0for file in session_files]    session_ids.sort(reverse=True)    return ApiResponse.success(message="会话列表获取成功", data=session_ids)

加载指定会话

在点击左侧的会话名称之后,就要查询出该会话对应的会话信息,并在消息展示栏将其展示出来。

# 获取指定会话信息@app.get('/api/sessions/{session_id}')def get_session(session_id: str):    print(f"获取会话信息:{session_id}")    session_file = get_session_file(session_id)    with open(session_file, "r", encoding="utf-8"as f:        session_data = json.load(f)    return ApiResponse.success(message="会话信息获取成功", data=session_data)

删除会话

在点击左侧会话名称之后的 x ,就要将当前的会话信息直接删除掉 。

# 删除指定会话信息@app.delete('/api/sessions/{session_id}')def delete_session(session_id: str):    print(f"删除会话信息:{session_id}")    session_file = get_session_file(session_id)    if os.path.exists(session_file):        os.remove(session_file)        return ApiResponse.success(message="会话信息删除成功",data=None)    else:        return ApiResponse.success(message="会话信息不存在",data=None)

日志记录

为了能够灵活的控制项目中日志的输出,我们可以通过官方提供的logging模块来输出日志,具体做法如下:

日志级别:日志级别就是给日志信息贴上的"重要性标签",常见的级别有:DEBUG、INFO、WARNING、ERROR、FATAL(日志级别依次升高)。

import logginglogging.basicConfig(    format='%(asctime)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s',    level=logging.INFO)

异常处理

项目中的功能较多,目前我们并未考虑异常处理,可以借助于FastAPI中的统一异常处理方案来处理异常。

# 异常处理器 统一处理异常信息# 异常处理器 统一处理异常信息@app.exception_handler(Exception)def handle_exception(request, exc: Exception):    logging.error(f"处理异常,请求路径:{request.url}, 异常信息:{exc}")    return JSONResponse(content={"code"500"message""服务器错误"})

 完整代码

import os.pathfrom datetime import datetimeimport jsonfrom typing import Anyfrom fastapi import FastAPIfrom pydantic import BaseModelfrom starlette.responses import FileResponse, JSONResponsefrom fastapi.staticfiles import StaticFilesfrom openai import OpenAIimport logginglogging.basicConfig(    format='%(asctime)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s',    level=logging.INFO)app = FastAPI(title="汉字迷盒")# 挂载静态文件的存放目录app.mount("/static",StaticFiles(directory="static"),name="static")# 系统提示词SYSTEM_PROMPT = """# 角色定义你是一个专门玩猜字谜的AI小助手,只进行字谜互动,不闲聊无关内容,全程纯文本交互,不使用表情符号。## 核心能力- 出字谜、判对错、给提示- 记忆已用谜题,确保会话内不重复- 简洁明快回应## 出题规则(严格执行!)1. 开场先友好打招呼,并随机出一道常见、简单、适合大众并必须符合逻辑推理的字谜,禁止使用生僻、低俗、网络烂梗。2. 题目格式:“谜面”(打一字)。3. 每次出题必须完全随机,禁止重复使用相同题目,也可以偶尔穿插使用,下面示例中的谜语。4. 新出题目时, 不要提示, 用户需要提示时, 或者答错时, 再给予合理的提示。## 判题规则(严格执行!)1. 用户只回复一个字时,直接视为答案。2. 答对:立即夸奖并揭晓谜底,格式如“太棒了!就是‘X’字!要不要再来一题?”3. 答错:告知不对,可给一句简短提示,但不泄露答案。格式如“不对哦,再想想~”4. 严禁在用户答错后直接公布答案!只有用户说“公布答案”或“不知道”等情况时才公布。## 互动流程1. 用户答对:夸奖 + 确认正确 + 询问“要不要再来一题?”2. 用户答错:告知不对 + 简单提示 + 鼓励继续猜3. 用户说“提示一下”:给出简短线索,不公布答案4. 用户说“公布答案”或“不知道”:揭晓谜底并解释 + 询问“要不要再来一题?”5. 用户说“换一题”“再来一题”:立即更换新字谜## 回复风格约束- 语气轻松有趣,但保持简洁- 全程只围绕字谜,拒绝回答其他问题- 回复不超过3句话- **绝对不要在回复中说“这个出过了,我来个新的”或类似表述** — 直接给出新谜语即可- 判题错误零容忍,不确定谜底时,先回复“我再想想”而不是乱判## 常见谜语类型及谜底参考示例, 仅仅为参照示例### 组合类- 「一加一不是二」= 王- 「二人不是天」= 夫- 「十口不是田」= 古### 包含类- 「一人在内」= 肉- 「口里有人」= 囚- 「门里有口」= 问- 「田里长草」= 苗- 「心里有你」= 您- 「山里有山」= 出- 「王头上有人」= 全- 「水上有石」= 泵### 半取类- 「半吃半拿」= 哈- 「半真半假」= 值- 「半青半紫」= 素- 「半朋半友」= 有- 「半推半就」= 扰- 「半山半水」= 汕### 象形类- 「三人又重逢」= 众- 「一口咬掉牛尾巴」= 告- 「两座山」= 出- 「三日又重逢」= 晶"""client = OpenAI(    api_key="xxxxx",    base_url="https://api.deepseek.com")#创建会话存放目录if not os.path.exists("sessions"):    os.mkdir("sessions")def generate_session_id():    return datetime.now().strftime("%Y-%m-%d_%H-%M-%S")#根据session_id 获取文件名def get_session_file(session_id: str):    return os.path.join("sessions", session_id + ".json")# 数据模型class ApiResponse(BaseModel):    code: int    message: str    data: Any  # 任意类型数据    @staticmethod    def success( message: str, data: Any):        return {"code"200"message": message, "data": data}#定义路径操作函数@app.get('/')def root():    logging.info("访问项目首页")    return FileResponse('static/index.html')# 新建会话@app.post("/api/sessions")def create_session():    logging.info("新建会话")    # 生成会话标识    session_id = generate_session_id()    # 组装会话信息,保存到文件中    session_data = {        'current_session': session_id,        'messages': []    }    with open(get_session_file(session_id), "w", encoding="utf-8"as f:        json.dump(session_data, f, ensure_ascii=False, indent=4)    # 返回数据    return ApiResponse.success(message="会话创建成功", data=session_id)class ChatRequest(BaseModel):    session_id: str    message: str# 与Ai交互@app.post("/api/chat")def chat(request: ChatRequest):    logging.info(f"与AI交互:{request.session_id} : {request.message}")    # 逻辑实现    # 1.加载json文件中的会话数据    session_file = get_session_file(request.session_id)    with open(session_file, "r", encoding="utf-8"as f:        session_data = json.load(f)    # 2. 构建Ai大模型交互的数据信息    messages = [{'role''system''content': SYSTEM_PROMPT}]    for message in session_data['messages']:        messages.append(message)    messages.append({'role''user''content': request.message})    # 3. 调用AI大模型 deepseek    response = client.chat.completions.create(        model="deepseek-chat",        messages=messages,        stream=False,        temperature=1.5,    )    # 4.获取响应数据    ai_response = response.choices[0].message.content    # 5.更新消息列表中的消息    messages.append({'role''assistant''content': ai_response})    session_data['messages'] = messages    # 6.保存会话信息到json文件中    with open(session_file, "w", encoding="utf-8"as f:        json.dump(session_data, f, ensure_ascii=False, indent=4)    # 7.返回数据    return ApiResponse.success(message='与AI交互成功',data=ai_response)@app.get('/api/sessions')def get_sessions():    logging.info("获取会话列表")    # 获取sessions文件夹下的所有目录名    session_files = os.listdir("sessions")    # 获取文件名中的会话Id    session_ids = [file.split('.')[0for file in session_files]    session_ids.sort(reverse=True)    return ApiResponse.success(message="会话列表获取成功", data=session_ids)# 获取指定会话信息@app.get('/api/sessions/{session_id}')def get_session(session_id: str):    logging.info(f"获取会话信息:{session_id}")    session_file = get_session_file(session_id)    with open(session_file, "r", encoding="utf-8"as f:        session_data = json.load(f)    return ApiResponse.success(message="会话信息获取成功", data=session_data)# 删除指定会话信息@app.delete('/api/sessions/{session_id}')def delete_session(session_id: str):    logging.info(f"删除会话信息:{session_id}")    session_file = get_session_file(session_id)    if os.path.exists(session_file):        os.remove(session_file)        return ApiResponse.success(message="会话信息删除成功",data=None)    else:        return ApiResponse.success(message="会话信息不存在",data=None)# 异常处理器 统一处理异常信息@app.exception_handler(Exception)def handle_exception(request, exc: Exception):    logging.error(f"处理异常,请求路径:{request.url}, 异常信息:{exc}")    return JSONResponse(content={"code"500"message""服务器错误"})if __name__ == '__main__':    import uvicorn    uvicorn.run(app,host='127.0.0.1',port=8000)

总结

Python生态系统的强大之处在于,它能让开发者用一套语言完成从数据采集、分析、可视化到Web应用、AI集成的全链路开发。希望通过本文的学习,你不仅掌握了具体的技术实现,更重要的是建立了"全栈思维"——能够从宏观角度设计系统架构,选择合适的工具链,最终交付高质量的技术解决方案。

技术之路,贵在实践。建议你在阅读完本文后,动手运行代码、调试功能、甚至在此基础上进行二次创新。唯有亲手敲过代码,才能真正将这些知识内化为自己的能力。祝你在Python开发的道路上越走越远!

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-22 01:19:36 HTTP/2.0 GET : https://f.mffb.com.cn/a/504273.html
  2. 运行时间 : 0.232419s [ 吞吐率:4.30req/s ] 内存消耗:4,997.30kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=b7617dc75580c17fe2a8daf019ebde76
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000901s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001301s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000601s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000684s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001201s ]
  6. SELECT * FROM `set` [ RunTime:0.000530s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001314s ]
  8. SELECT * FROM `article` WHERE `id` = 504273 LIMIT 1 [ RunTime:0.012729s ]
  9. UPDATE `article` SET `lasttime` = 1787332777 WHERE `id` = 504273 [ RunTime:0.002516s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000687s ]
  11. SELECT * FROM `article` WHERE `id` < 504273 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001525s ]
  12. SELECT * FROM `article` WHERE `id` > 504273 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001142s ]
  13. SELECT * FROM `article` WHERE `id` < 504273 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.002613s ]
  14. SELECT * FROM `article` WHERE `id` < 504273 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.013932s ]
  15. SELECT * FROM `article` WHERE `id` < 504273 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.018815s ]
0.234159s