1. 从零建站这件事为什么我选了 WorkBuddy 加 Flask 这套组合去年年底我接手了一个很小的需求帮一个做农产品批发的朋友搭一个能每天更新价格行情的小站点。要求听起来不复杂——能发布每日价格、能按品类和日期查、手机上看不崩、后台自己能改数据预算几乎为零。但真动手的时候选型这一步就卡了我两天。摆在面前的路其实就三条。第一条是 Shopify 这类托管电商开箱即用但它是为卖货设计的我要的是“信息发布查询”硬套会别扭而且每月固定成本对一个小站点来说不划算。第二条是 WordPress生态成熟、插件多但它的强项是内容管理一旦我要做自定义的价格查询逻辑和数据结构就得跟主题和插件打架改起来束手束脚。第三条就是源码自建用 Flask 加 SQLite 自己写。我最后选了第三条原因很直接这个站点的核心是“结构化的价格数据轻量查询”不是复杂的内容运营自己写反而最省心而且 Flask 足够轻SQLite 一个文件就是整个数据库部署和备份都简单到离谱。这里就引出了 WorkBuddy 的角色。很多人第一次听到 WorkBuddy 会把它和 CodeBuddy 搞混我一开始也分不清。简单说CodeBuddy 更偏向纯代码补全和函数级生成而 WorkBuddy 的定位是“工作台”式的协作助手它能理解项目上下文、帮你规划任务、生成整段模块代码、还能按你自定义的指令去执行重复性工作。对我这种“一个人当三个人用”的独立开发者来说WorkBuddy 最大的价值不是帮我写某一行代码而是帮我把“建站”这件大事拆成可执行的小任务并且在日更这种高频重复场景里替我扛掉大量机械劳动。这也是我写这篇实操记录的初衷——网上关于 WorkBuddy 使用教程、WorkBuddy 从入门到精通 这类内容不少但真正把它放进一个完整建站项目里、并且坚持日更跑通的记录并不多我想把踩过的坑和跑通的路径完整摊开。这篇文章适合谁看如果你是完全没碰过 Flask 和 SQLite 的新手我会把 Python 安装、环境配置、数据库建表这些基础环节讲清楚你照着做能跑起来如果你已经会 Flask但卡在“怎么把日常更新自动化”“怎么让 WorkBuddy 真正帮上忙”这些地方那第二、三部分的实操细节和自定义指令会更对你有用。整套方案的核心技术栈就是 Python Flask SQLite配合 WorkBuddy 做任务编排和代码生成最终实现一个能日更、能查询、能自己维护的轻量站点。2. 整体设计与思路拆解为什么是这套架构2.1 需求倒推架构而不是先选技术再找场景我见过太多人建站的第一步是“我要用某某框架”结果做到一半发现框架的特性和需求对不上。我的习惯是先把需求翻译成数据流再决定用什么。这个农产品价格站点的需求拆开其实就四件事第一每天录入一批价格数据字段包括品类、规格、单价、日期、备注第二前台能按品类筛选、按日期排序展示第三支持简单的关键词搜索第四后台能增删改且不需要复杂的权限体系。把这四件事翻译成技术语言需要一个关系型数据库存结构化数据需要一个轻量 Web 框架提供路由和模板渲染需要一个能定时或半自动触发数据录入的机制。SQLite 天然适合这种“单机、低并发、数据量不大”的场景它不需要单独起服务一个.db文件拷走就是完整备份。Flask 的路由和 Jinja2 模板机制写查询页和详情页非常顺手代码量小调试直观。至于数据录入我没上复杂的后台管理系统而是用 Flask 写了一个受简单口令保护的管理页配合 WorkBuddy 生成批量导入脚本日更时基本是“整理好表格→跑脚本→刷新页面”三步。提示不要因为 SQLite “看起来简单”就低估它。对于日更、单表几千到几万行的场景它的读写性能完全够用真正需要警惕的是并发写入——后面排查部分我会专门讲这个坑。2.2 WorkBuddy 在这套架构里到底承担什么把 WorkBuddy 当成“更聪明的代码补全”是浪费它。我在这个项目里给它的定位是三层任务规划层、代码生成层、重复劳动替代层。任务规划层指的是建站初期我把“搭一个价格查询站”这个模糊目标丢给它让它帮我拆成“环境准备→数据库设计→路由设计→模板设计→数据导入→部署”这样的阶段清单我再按清单推进避免漏项。代码生成层指的是像 SQLite 建表语句、Flask 的路由函数、Jinja2 模板里的循环渲染这些有固定套路的代码我描述清楚字段和逻辑后让它生成初稿我再改。重复劳动替代层是最关键的——日更意味着每天都要做相似的数据清洗和导入我通过 WorkBuddy 的自定义指令把这套流程固化成一个可复用的操作每天只需要替换源数据文件。这里要澄清一个常见误解WorkBuddy 和 CodeBuddy 不是二选一的关系。我在实际使用中写具体函数逻辑时会借助 CodeBuddy 的补全而项目级的规划、跨文件的改动、自定义工作流则交给 WorkBuddy。两者配合效率比单用任何一个都高。至于网上流传的 WorkBuddy 从入门到精通 PDF 下载 这类资源我的建议是别急着找“大全”先把官方文档里关于自定义指令和工作台的部分读透比看十份二手教程都管用。2.3 为什么不上重型方案一次真实的取舍中途我动摇过一次想换成 Django理由是它自带 admin 后台省得自己写管理页。但算了一笔账Django 的 admin 确实省事可它带来的是一整套约定和依赖学习成本、部署体积、调试复杂度都上去了而我需要的只是一个能改数据的页面。最后我用 Flask 加一个不到八十行的管理路由就解决了还完全可控。这个取舍的逻辑值得说清楚当你的需求是“一个点”不要为了这个点引入“一个面”。SQLite 对 Django 来说也偏轻属于杀鸡用牛刀。同理前端我也没上 React 或 Vue直接用 Jinja2 服务端渲染加一点原生 JS 做筛选首屏快、SEO 友好、维护简单。3. 核心细节解析与实操要点3.1 环境准备Python 安装与环境隔离的正确姿势第一步是 Python 安装。Windows 用户去官网下安装包时务必勾选“Add Python to PATH”这一步漏了后面在命令行敲python会提示找不到命令是新手最高频的坑。装完后在终端验证python --version pip --version能正常输出版本号就说明 PATH 配好了。macOS 和 Linux 用户一般自带 Python3但建议用python3和pip3明确区分避免和系统自带的 Python2 混淆。WorkBuddy 在 Linux 和 Ubuntu 环境下同样可用如果你是在服务器上开发装完 Python 后建议顺手装python3-venv。接下来是环境隔离这一步很多人跳过结果项目依赖和系统环境互相污染后面出问题极难排查。我的做法是每个项目一个虚拟环境python -m venv venv # Windows venv\Scripts\activate # macOS / Linux source venv/bin/activate激活后命令行前面会出现(venv)标识。然后在虚拟环境里装依赖pip install flask如果你用 VSCode 开发记得在 VSCode Python 环境配置里把解释器指向这个虚拟环境否则编辑器提示的库和实际运行用的库会对不上这个坑我踩过表现为“代码里明明能跳转定义运行却报 ModuleNotFoundError”。3.2 数据库设计SQLite 建表与字段类型选择SQLite 的建表语句不复杂但字段类型的选择直接影响后面查询和展示的顺畅度。我的价格表设计如下CREATE TABLE price ( id INTEGER PRIMARY KEY AUTOINCREMENT, category TEXT NOT NULL, spec TEXT, price REAL NOT NULL, unit TEXT DEFAULT 元/斤, record_date TEXT NOT NULL, note TEXT, created_at TEXT DEFAULT (datetime(now, localtime)) );几个细节值得展开。record_date我用 TEXT 存YYYY-MM-DD格式而不是用日期类型原因是 SQLite 的日期处理相对弱用文本存反而在排序和范围查询时更直观WHERE record_date BETWEEN 2024-01-01 AND 2024-01-31这种写法可读性极高。price用 REAL虽然浮点数有精度问题但价格展示到分位足够真要严格可以用整数存“分”。created_at用默认值自动填省得每次插入都手动传。建好表后我强烈建议装一个可视化工具。DB Browser for SQLite 是免费的打开.db文件就能像 Excel 一样看数据、改数据、跑 SQL对调试帮助巨大。Android Studio 里也有 SQLite 的可视化工具但那是给移动开发用的Web 项目用 DB Browser 更顺手。如果你习惯用 C# 生态也可以用 C# 打开 SQLite 数据库的工具但没必要为了看数据专门换语言。注意SQLite 数据库文件默认是不加密的任何人拿到.db文件就能读全部数据。如果你的价格数据涉及商业机密要么在应用层做字段加密要么把数据库文件放在 Web 根目录之外并严格控制服务器文件权限。SQLite 本身支持加密扩展但配置较麻烦小项目更推荐用文件权限来兜底。3.3 Flask 路由设计把查询逻辑写清楚Flask 的核心是路由。这个站点我设计了三个主要路由首页列表、按品类筛选、搜索。首页路由大致长这样from flask import Flask, render_template, request import sqlite3 app Flask(__name__) def get_db(): conn sqlite3.connect(price.db) conn.row_factory sqlite3.Row return conn app.route(/) def index(): category request.args.get(category, ) keyword request.args.get(q, ) conn get_db() sql SELECT * FROM price WHERE 11 params [] if category: sql AND category ? params.append(category) if keyword: sql AND (category LIKE ? OR note LIKE ?) params.extend([f%{keyword}%, f%{keyword}%]) sql ORDER BY record_date DESC, id DESC LIMIT 100 rows conn.execute(sql, params).fetchall() conn.close() return render_template(index.html, rowsrows)这里有个新手常问的问题Flask 怎么查看从客户端获取的变量数据类型答案是request.args拿到的永远是字符串request.form也是字符串需要数字就自己int()转换别指望框架帮你转。另外conn.row_factory sqlite3.Row这行很关键它让查询结果可以像字典一样用列名访问模板里写row[category]而不是row[1]可读性天差地别。参数化查询用?占位符这是防 SQL 注入的基本功千万别用字符串拼接把用户输入直接塞进 SQL。我见过有人图省事写fWHERE category {category}一旦有人构造恶意输入整个库都危险。3.4 模板渲染Jinja2 里那些容易忽略的细节模板部分我用的是 Jinja2循环渲染数据行{% for row in rows %} tr td{{ row[category] }}/td td{{ row[spec] or - }}/td td{{ %.2f|format(row[price]) }}/td td{{ row[record_date] }}/td /tr {% endfor %}{{ row[spec] or - }}这个写法处理空值很实用比写 if 判断简洁。价格用%.2f|format()保留两位小数避免出现3.1000000001这种浮点误差展示。Jinja2 默认会转义 HTML所以用户输入的备注里如果有特殊字符不会被当成标签执行这是安全默认值别去关它。4. 实操过程与核心环节实现4.1 从零到能跑完整搭建流程我把整个搭建过程按时间顺序复盘一遍你可以直接照着走。第一步建项目目录结构如下price_site/ ├── app.py ├── price.db ├── templates/ │ ├── index.html │ └── admin.html └── static/ └── style.css第二步写app.py把数据库连接、路由、启动代码放进去。第三步用 DB Browser 手动建表或者写一个init_db.py脚本跑一次建表语句。第四步写模板。第五步本地跑起来flask --app app run --debug--debug模式会在代码改动后自动重启开发期非常方便但上线一定要关掉否则有安全风险。浏览器打开http://127.0.0.1:5000能看到页面就说明通了。4.2 日更数据导入WorkBuddy 自定义指令的实战用法日更是这个项目的核心场景也是最值得用 WorkBuddy 提效的地方。我每天的工作流是这样的朋友把当天的价格发我一个 Excel 或 CSV我需要清洗成统一格式再导入数据库。手动做的话每天要花十几分钟一个月下来就是好几个小时。我用 WorkBuddy 的自定义指令把这套流程固化了下来。具体做法是我先写一个通用的导入脚本import_data.py它读取一个标准格式的 CSV逐行插入数据库并做去重同品类同规格同日期已存在则更新而非新增import csv import sqlite3 def import_csv(path): conn sqlite3.connect(price.db) with open(path, newline, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: existing conn.execute( SELECT id FROM price WHERE category? AND spec? AND record_date?, (row[category], row[spec], row[record_date]) ).fetchone() if existing: conn.execute( UPDATE price SET price?, note? WHERE id?, (row[price], row.get(note, ), existing[id]) ) else: conn.execute( INSERT INTO price (category, spec, price, record_date, note) VALUES (?,?,?,?,?), (row[category], row[spec], row[price], row[record_date], row.get(note, )) ) conn.commit() conn.close()这里的UPDATE语句就是 SQLite update 语句的典型用法配合前面的存在性检查实现了“有则更新、无则插入”的 upsert 效果。然后我把“读取指定 CSV 并导入”这件事配置成 WorkBuddy 的一个自定义指令每天只需要把新文件放到指定目录触发指令即可。WorkBuddy 的自定义指令推荐配置思路是把“输入是什么、要做什么、输出到哪”描述清楚越具体越稳定。提示CSV 的编码是个高频坑。Excel 导出的 CSV 在中文 Windows 上常是 GBK 编码直接按 utf-8 读会报错或乱码。稳妥做法是导入前统一转成 UTF-8或者在脚本里做编码探测。我现在的习惯是让朋友直接发 UTF-8 的 CSV省去转换。4.3 部署上线让站点真正能被访问本地跑通只是第一步要让人访问得部署。小项目我推荐两种方式一是用轻量的云服务器装好 Python 环境用 Gunicorn 加 Nginx 反向代理跑 Flask二是用支持 Python 的托管平台省去运维。Gunicorn 启动命令大致是gunicorn -w 2 -b 127.0.0.1:8000 app:app-w 2表示两个工作进程对低并发足够。Nginx 负责把外部请求转发到 8000 端口同时处理静态文件。这里有个 SQLite 的并发注意点多个 Gunicorn 工作进程同时写数据库可能触发database is locked解决办法是控制写入频率、给连接设置超时或者干脆把写操作集中到单进程处理。我的站点读多写少日更时基本没人访问所以这个问题不突出但你要心里有数。5. 常见问题与排查技巧实录5.1 高频问题速查表问题现象可能原因排查与解决命令行提示 python 不是内部命令安装时没勾 PATH重装并勾选 Add to PATH或手动配环境变量ModuleNotFoundError: flask虚拟环境没激活或装错环境确认命令行有 (venv) 标识重新 pip install数据库查询报 no such table建表脚本没跑或连错库文件用 DB Browser 打开确认表存在检查连接路径中文显示乱码编码不一致统一用 UTF-8CSV 导入前转码database is locked并发写入冲突减少写并发设置连接 timeout页面样式不生效静态文件路径错检查 static 目录和 url_for 写法5.2 几个只有踩过才知道的坑第一个坑是日期排序。我一开始用ORDER BY record_date DESC结果发现同一天的数据顺序乱跳因为同日期内没有稳定排序。加上id DESC作为第二排序键后就稳定了。第二个坑是浮点展示前面提过一定要格式化。第三个坑是 WorkBuddy 生成代码后的“想当然”——它生成的代码逻辑通常对但字段名、表名可能和你实际的不一致生成后必须逐行核对尤其是 SQL 里的列名。我吃过一次亏生成的 UPDATE 语句列名拼错跑的时候没报错但数据没更新排查了半天。第四个坑是关于数据备份。SQLite 虽然一个文件就是全部但正因为简单很多人忘了备份。我的做法是每天导入完成后自动复制一份带日期的.db文件到备份目录保留最近三十天。这个动作也交给 WorkBuddy 的定时任务去做几乎零成本但关键时刻能救命。5.3 关于 WorkBuddy 使用的几点个人体会用了一段时间后我最大的感受是WorkBuddy 的价值取决于你给它的上下文质量。你描述得越具体它产出越可用。比如“帮我写个导入脚本”和“帮我写个读取 UTF-8 CSV、按 categoryspecrecord_date 去重、存在则更新 price 字段的 SQLite 导入脚本”得到的结果完全不是一个层次。另外WorkBuddy 工作台适合管理多步骤任务把建站拆成阶段后每天推进一点进度一目了然。至于 WorkBuddy 国际版和国内版的差异主要在使用环境和部分集成上核心的工作台和自定义指令能力是一致的按自己所在环境选就行。最后分享一个小技巧把常用的自定义指令整理成一个清单文档标注每个指令的输入输出和适用场景。日更这种重复场景指令库越完善你每天花的时间越少。我现在整套日更流程从收到数据到页面更新稳定在五分钟以内这在没有 WorkBuddy 之前是不敢想的。