SQL 过去像厨师口袋里那张油乎乎的小票:写给自己看,掉了也没人追。我看 Datasette 1.0a33 干得最狠的一件事,就是把这张小票裱进前台,做成可上架、可授权、可追踪、可删改的菜单。它把查询升格为可运营对象。
多数人看 2026 年 6 月 11 日发布的 1.0a33,看到的是几个功能点:存储查询能在网页里编辑、删除了;?_extra= 这类参数能把更多元信息吐给程序了;顺手补了两个安全洞。若只盯着功能名,它像一次勤勉的维护更新。可要是盯着“查询在组织里怎么活”,味道就变了。
反常识恰恰在这里:数据产品里最该被管理的,不是数据库,不是表,甚至不是图表,而是查询。数据库太像仓库,图表太像橱窗,只有查询才是那台叉车。谁握着它,谁就决定今天搬什么出来,给谁看,什么时候改口径,出了事算谁的。
数据库是仓库,图表是橱窗,查询才是叉车。
周一早上九点,区城运中心的数据员小杜要交一份“最近七天被重复投诉三次以上的电梯”清单。旧办法里,这是一段躺在聊天记录里的 SQL(数据库查询语句):有人把“三次”改成“两次”,有人把“七天”改成“三天”,最后谁也说不清哪一版才是正式口径。Datasette 把它做成一个有名字、有固定链接、能带参数、能设权限的存储查询。它不再是“杜姐昨晚发的那段代码”,而是一个能被搜索、能被引用、能被替换版本的正式物件。
一段查询如果只能活在作者的剪贴板里,它就不是资产,只是手汗。
下午三点,市博物馆数字化助理林岚要给外包志愿者开放一条“可公开且有修复记录的青铜器”查询。数据库不能全开,表也不能乱翻。过去只能让工程师代跑,像把后厨钥匙交给每个来打饭的人。现在她可以把查询设成私有、公开,甚至区分“可信”与“不可信”。这不是多一个按钮,这是多一层制度。软件圈常见一种幼稚病:把能跑通当成熟,把能上线当文明。其实真正的文明,是对象有户口,动作有边界,协作有回执。
给 SQL 加按钮,不算产品;给查询加身份,才算制度。
晚上十点,社区药房运营小陈发现一批药品库存状态写错了,要批量修正。传统工具里,写操作要么直冲数据库,要么提工单排队。Datasette 从 2026 年 5 月 29 日的 1.0a31 开始给出写查询页面,到 5 月 31 日的 1.0a32 又让 RETURNING(把刚改动的行立刻返回)这类写法跑通。于是修改不再像黑箱里按一下按钮听天由命,而像柜台改账,改完立刻拿到回单,甚至能跳到那条刚插进去的新记录。读和写都被放进同一套“查询对象”逻辑里,这就不是“查一下”,这是“办一件事”。
运营不是把功能做多,而是让对象能被命名、被分发、被审计、被回收。
所以 1.0a33 的编辑和删除存储查询,看着平平,实际是补上了闭环。一个东西,能新建,能搜索,能授权,能修改,能下架,才能叫对象;否则只是一次性耗材。Datasette 现在对查询做的,已经很像电商后台对商品做的事,只不过它卖的不是牙膏,不是拖鞋,而是“怎样看数据、怎样动数据”这条路径本身。
更关键的是,?_extra=(让 JSON,也就是给程序看的结构化返回,多吐出元信息的参数)从表页延伸到行页和查询页。以前接口多半只给你结果;现在它还能把列信息、底层查询、元数据、是否私有这些背景一起端上来。以前像端出一盘鱼;现在连鱼名、产地、秤和冷链单也一起给你。运营从来不只是内容本身,运营还包括内容的说明书、权限表和售后单。
Datasette 甚至把这些查询明明白白放进自己的内部 SQLite(轻量数据库) 的 queries 表里。请注意这个动作的意味:数据库里存的不只是“数据”,还存“怎么看数据”。这一下,查询从动词变成名词,从临时手势变成组织记忆,从个人手艺变成集体设施。
真正的 1.0,不是软件敢发布,而是组织敢依赖。
也因此,1.0a33 修的那两个安全问题并不是边角料。一个是表名、列名里夹着 ] 时可能被钻成 SQL 注入;一个是跳转路径可能把人带到站外。门锁、护栏、回执,听上去都不性感,可一旦你承认“查询是要被运营的对象”,这些东西就从配件变成主体。散装零件可以靠侥幸,货架商品不行。
我对 Datasette 这一轮 1.0 预发布版的判断很明确:它真正完成的,不是“让人更方便地写查询”,而是“让组织可以正式地管理查询”。这比多一个图表、多一个按钮、多一层皮肤重要得多。前者是在加功能,后者是在改社会关系。
技术人习惯把工具理解成能力,人类学更关心工具如何嵌进关系。Datasette 1.0a33 的意思,正是在这里:查询不再只是数据库后厨里的一次动作,而是前台货架上的一个单位。它可以被命名,被观看,被信任,被限制,被修改,被下架,被程序再次调用。说得直白一点,Datasette 没有把查询做得更像代码,它把查询做得更像商品,更像制度,更像组织里的“东西”。
而这,才是 1.0 的气象。
参考:1.0a31 / 1.0a32 / 1.0a33 / Running SQL queries / Pages and API endpoints / JSON API / Internals for plugins