MySQL 综合应用实战:用 Python+Html 搭一套带 TaoToken 配置的 Flask 数据看板
发布时间:2026/9/26 13:26:00来源:尧图网络
1. 从一张 Excel 到实时看板为什么选 Flask pymysql如果你手里有一张不断更新的 MySQL 学生表或业务表每次想看数据都要打开客户端敲SELECT * FROM ...或者导出 Excel 再手动刷新那这套流程迟早会让人烦躁。更实际的做法是用 Python 起一个轻量 Web 服务把 MySQL 里的数据通过接口吐出来再用一个 Html 页面渲染成表格或卡片浏览器一刷新就能看到最新状态。这就是本地数据看板的最小闭环。Flask 适合这个场景的原因很直接它不强制项目结构一个app.py就能跑起来路由和视图函数一一对应调试成本低。pymysql 则是 Python 连接 MySQL 最常用的库之一纯 Python 实现安装即用配合DictCursor返回字典结果直接能转 JSON 给前端。整套链路是MySQL 存数据 → pymysql 读数据 → Flask 暴露接口 → Html fetch 渲染页面。这篇会交付一套可复制的 Flask 项目骨架包含数据库连接配置、CRUD 接口、前端页面以及把 TaoToken 的统一 Key/API 通道写进config.py的片段。适合谁有 Python 基础、想快速搭一个本地数据看板、又不想引入重型框架的开发者。下面从环境准备开始一步步把项目跑起来。2. TaoToken 前置统一 Key 与 API 通道配置在写 Flask 代码之前先把模型调用通道的配置准备好。TaoToken 提供统一的 API 入口把不同模型的 Key 收敛到一个地方管理后续如果看板要加“自然语言查询数据”或“自动生成报表摘要”这类功能直接复用这套配置即可不用每个脚本单独维护密钥。你需要先拿到一个 API Key。登录后进入控制台在 API Keys 页面创建一个新 Key复制保存。这个 Key 就是后续所有请求的凭证。控制台入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewriteAPI 基础地址是https://taotoken.net/api注意这个地址不带 UTM 参数直接用于代码里的base_url。把 Key 和地址写进项目的config.py和数据库配置放在一起这样整个项目只有一个配置中心改起来不散。注意API Key 不要硬编码在提交到 Git 的文件里。本地开发可以用环境变量读取或者把config.py加入.gitignore只提交config.example.py。3. 可复制配置项目骨架与数据库连接先建目录结构。一个最小可用的 Flask 数据看板长这样flask_dashboard/ ├── app.py # Flask 主程序路由与接口 ├── config.py # 数据库 TaoToken 配置 ├── db.py # pymysql 连接工具 ├── templates/ │ └── index.html # 前端页面 └── requirements.txt安装依赖pip install flask pymysqlrequirements.txt内容flask pymysql接着写config.py把 MySQL 和 TaoToken 的配置都放进来# config.py import os # MySQL 配置 DB_CONFIG { host: 127.0.0.1, port: 3306, user: root, password: os.getenv(MYSQL_PWD, 123456), database: python_mysql, charset: utf8mb4, } # TaoToken 统一通道配置 TAOTOKEN_CONFIG { api_key: os.getenv(TAOTOKEN_API_KEY, sk-你的Key), base_url: https://taotoken.net/api, model: claude-sonnet-4-20250514, }这里charset必须写utf8mb4不是utf-8。MySQL 里utf8和utf8mb4是两回事写错会导致中文乱码或 emoji 存不进去。**DB_CONFIG这种解包写法等价于把字典里的键值对逐个展开成host...、user...传给pymysql.connect()代码更干净。数据库表沿用学生表结构先在 MySQL 里执行CREATE DATABASE IF NOT EXISTS python_mysql DEFAULT CHARSET utf8mb4; USE python_mysql; CREATE TABLE student ( sid INT PRIMARY KEY AUTO_INCREMENT, sname VARCHAR(20) NOT NULL, age INT, gender VARCHAR(10) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;然后写db.py封装连接获取和关闭避免每个接口重复写连接代码# db.py import pymysql from config import DB_CONFIG def get_conn(): 获取数据库连接返回字典游标 conn pymysql.connect(**DB_CONFIG) return conn def query_all(sql, argsNone): 通用查询返回字典列表 conn get_conn() cursor conn.cursor(pymysql.cursors.DictCursor) try: cursor.execute(sql, args) return cursor.fetchall() finally: cursor.close() conn.close() def execute(sql, argsNone): 通用增删改返回受影响行数 conn get_conn() cursor conn.cursor() try: rows cursor.execute(sql, args) conn.commit() return rows except Exception as e: conn.rollback() raise e finally: cursor.close() conn.close()DictCursor的作用是把查询结果从元组(1, 张三)变成字典{sid: 1, sname: 张三}取值用字段名而不是下标可读性高很多而且能直接jsonify转 JSON。实际开发里基本都用它。4. 验证请求Flask 接口与 Html 页面渲染app.py里定义四个接口对应查询、新增、修改、删除# app.py from flask import Flask, request, jsonify, render_template from db import query_all, execute app Flask(__name__) app.route(/) def index(): return render_template(index.html) app.route(/get_student, methods[GET]) def get_student(): data query_all(SELECT * FROM student ORDER BY sid) return jsonify({code: 200, data: data}) app.route(/add_student, methods[POST]) def add_student(): d request.get_json() execute( INSERT INTO student(sname, age, gender) VALUES (%s, %s, %s), (d.get(sname), d.get(age), d.get(gender)), ) return jsonify({code: 200, msg: 新增成功}) app.route(/update_student, methods[POST]) def update_student(): d request.get_json() execute( UPDATE student SET age %s WHERE sid %s, (d.get(age), d.get(sid)), ) return jsonify({code: 200, msg: 修改成功}) app.route(/del_student, methods[POST]) def del_student(): d request.get_json() execute(DELETE FROM student WHERE sid %s, (d.get(sid),)) return jsonify({code: 200, msg: 删除成功}) if __name__ __main__: app.run(debugTrue, port5000)注意 SQL 里统一用%s占位符不要用 f-string 拼接。拼接字符串会有 SQL 注入风险%s是 pymysql 的参数化查询安全且能自动处理类型转义。前端templates/index.html用原生 fetch 调接口页面加载时自动拉数据渲染表格!DOCTYPE html html langzh-CN head meta charsetUTF-8 title学生数据看板/title style body { font-family: sans-serif; margin: 24px; } table { border-collapse: collapse; width: 640px; margin-top: 16px; } th, td { border: 1px solid #ccc; padding: 8px; text-align: center; } th { background: #f5f5f5; } input { padding: 6px; margin-right: 8px; } button { padding: 6px 12px; cursor: pointer; } /style /head body h2学生数据看板/h2 div input idsname placeholder姓名 input idage typenumber placeholder年龄 input idgender placeholder性别 button onclickaddStudent()新增/button /div table thead trth学号/thth姓名/thth年龄/thth性别/thth操作/th/tr /thead tbody idtbody/tbody /table script async function loadList() { const res await fetch(/get_student); const result await res.json(); const tbody document.getElementById(tbody); tbody.innerHTML ; if (result.code 200) { result.data.forEach(item { const tr document.createElement(tr); tr.innerHTML td${item.sid}/td td${item.sname}/td td${item.age}/td td${item.gender}/td td button onclickupdateAge(${item.sid})改年龄/button button onclickdelStudent(${item.sid})删除/button /td; tbody.appendChild(tr); }); } } async function addStudent() { const body { sname: document.getElementById(sname).value, age: document.getElementById(age).value, gender: document.getElementById(gender).value, }; const res await fetch(/add_student, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify(body), }); const result await res.json(); alert(result.msg); loadList(); } async function updateAge(sid) { const age prompt(请输入新年龄); if (!age) return; await fetch(/update_student, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ sid, age }), }); loadList(); } async function delStudent(sid) { if (!confirm(确定删除)) return; await fetch(/del_student, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ sid }), }); loadList(); } window.onload loadList; /script /body /html启动服务python app.py控制台出现Running on http://127.0.0.1:5000后浏览器打开这个地址。页面加载时会自动请求/get_student表格里应该能看到数据库里的学生记录。输入姓名、年龄、性别点新增数据写入 MySQL 后列表自动刷新。改年龄和删除同理操作完页面即时更新。验证接口是否正常也可以直接用 curlcurl http://127.0.0.1:5000/get_student返回类似{code: 200, data: [{sid: 1, sname: 张三, age: 20, gender: 男}]}看到这个结构说明 pymysql 读取、Flask 序列化、前端渲染整条链路都通了。5. 本篇常见错排查页面打开是空白或表格无数据。先看浏览器控制台 Network 里/get_student的返回。如果是 500看 Flask 控制台的报错栈多半是数据库连接失败或表不存在。检查config.py里的host、user、password、database是否和实际一致MySQL 服务是否启动。中文显示成问号或乱码。三个地方都要是utf8mb4数据库建库时的DEFAULT CHARSET、表建表时的DEFAULT CHARSET、pymysql 连接配置里的charset。任何一处写成utf8或utf-8都可能出问题。utf-8在 MySQL 里不是合法字符集名会直接报Unknown charset。新增或修改后数据没变。检查execute函数里有没有conn.commit()。pymysql 默认不自动提交增删改必须显式 commit 才生效。如果中途抛异常rollback()会撤销操作这是事务保护不是 bug。前端 POST 请求后端收不到数据。两个原因一是前端 fetch 没设headers: {Content-Type: application/json}后端request.get_json()会返回 None二是后端用了request.form去接 JSON 数据应该用request.get_json()。端口 5000 被占用。改app.run(port5001)即可。macOS 上 5000 端口有时被 AirPlay 占用换个端口最省事。跨域问题。本篇前后端同源都在 Flask 里不会触发跨域。如果以后把前端单独部署到别的端口需要装flask-cors并配置允许来源。6. 把 TaoToken 接进看板下一步可以做什么数据看板跑起来之后一个自然的延伸是加“自然语言查询”或“自动摘要”功能。比如在页面上加一个输入框用户输入“年龄大于 18 的学生有哪些”后端把这句话和表结构一起发给模型模型返回 SQL再执行查询渲染结果。这时候 TaoToken 的统一通道就派上用场了。调用方式很简单用requests或openaiSDK 指向 TaoToken 的 base_url# ai_helper.py import requests from config import TAOTOKEN_CONFIG def ask_model(prompt): headers { Authorization: fBearer {TAOTOKEN_CONFIG[api_key]}, Content-Type: application/json, } payload { model: TAOTOKEN_CONFIG[model], messages: [{role: user, content: prompt}], } resp requests.post( f{TAOTOKEN_CONFIG[base_url]}/v1/chat/completions, headersheaders, jsonpayload, timeout30, ) return resp.json()[choices][0][message][content]想先验证模型通道是否通可以直接在模型对话页面发一条测试消息确认 Key 和地址配置正确模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite如果后续要做长期编码或 Agent 类任务比如让模型自动生成报表、定时跑数据清洗脚本可以了解 Coding PlanCoding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite接入过程中遇到 Key 或请求格式问题查接入文档最直接接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite整套看板的骨架到这里就完整了。数据库连接、接口、页面渲染、错误排查都覆盖到你可以直接复制代码跑起来再按自己的表结构改 SQL 和字段。下一步加图表库比如 ECharts或者接模型做智能查询都是在这个骨架上叠功能不用推倒重来。
网站建设高端定制企业官网