news 2026/9/23 11:21:16

EdgeDB(Gel)DELETE 语句实战指南:从 Cheatsheet 出发掌握数据删除的两种范式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
EdgeDB(Gel)DELETE 语句实战指南:从 Cheatsheet 出发掌握数据删除的两种范式

EdgeDB(Gel)DELETE 语句实战指南:从 Cheatsheet 出发掌握数据删除的两种范式

【免费下载链接】edgedbGel supercharges Postgres with a modern data model, graph queries, Auth & AI solutions, and much more.项目地址: https://gitcode.com/gh_mirrors/ed/edgedb

本文基于 EdgeDB 官方 Cheatsheet 中的 "Deleting data" 一页展开,系统讲解在 EdgeDB(Gel)中删除对象的两种核心写法:直接对类型集做filter删除,以及通过反向链接(backlink)定位并删除。读完本文,你将掌握delete语句的完整语法、filter/order by/offset/limit子句的语义、删除返回值的使用方式,以及链接删除策略(link deletion policy)与级联删除的底层机制,并能直接把这些模式应用到自己的 schema 中。

从 Cheatsheet 说起:两种删除范式

原 Cheatsheet(docs/resources/cheatsheets/delete.rst)以一组电影评论(UserMovieReview)schema 为背景,给出了两种删除某个用户所有评论的写法。其中用到的对象类型定义在 docs/resources/cheatsheets/objects.rst,要点如下:

type User extending HasImage { required name: str { constraint exclusive; } } type Review { required body: str; required rating: int64 { constraint min_value(0); constraint max_value(5); } required flag: bool { default := False; } required author: User; required movie: Movie; required creation_time: datetime { default := datetime_current(); } }

注意Review.authorrequired author: User,即每条评论都有一条指向作者的多对一链接;反之,从User出发可以通过反向链接.<author[is Review]找到该用户写过的全部评论。

范式一:直接按链接路径过滤删除

第一种写法直接指定要删除的类型,并通过链接路径过滤:

delete Review filter .author.name = 'trouble2020'

要点在于filter子句里的路径表达式.author.name:EdgeQL 会自动沿Review -> author -> User.name解析,筛出所有作者名为trouble2020Review对象并删除。这符合直觉,也是日常最常用的方式。

范式二:通过反向链接(backlink)删除

Cheatsheet 给出的"另一种方式"利用了反向链接遍历:

delete ( select User filter .name = 'troll2020' ).<author[is Review]

逐步拆解:

  1. select User filter .name = 'troll2020':先找出目标用户;
  2. .<author[is Review]:对该用户沿author链接的反方向做一次类型过滤遍历,得到"指向该用户的所有Review";
  3. 整个括号表达式是一个对象集合,delete直接作用于这个集合。

这里的[is Review]是类型过滤(type filter),保证反向遍历只保留Review类型,避免把其它也指向该User的对象误纳入删除范围。这种写法在"从一个对象出发删除其所有关联对象"的场景中非常自然,也常与update语句中的-=一起用于先解除链接再删除的模式(见下文链接删除策略)。

DELETE 语句的完整语法与语义

Cheatsheet 只是速查,完整的语句形式定义在 docs/reference/reference/edgeql/delete.rst:

[ with <with-item> [, ...] ] delete <expr> [ filter <filter-expr> ] [ order by <order-expr> [direction] [then ...] ] [ offset <offset-expr> ] [ limit <limit-expr> ] ;

几个关键语义点:

  • with子句:既可以声明模块别名,也可以声明表达式别名,供delete语句内部引用(详见 docs/reference/edgeql/with.rst)。
  • 整个delete <expr> ...语句是delete (select ...)的语法糖:<expr>filterorder byoffsetlimit共同决定"要删除的集合",其成型方式与显式select完全一致。这解释了为什么 Cheatsheet 范式二能直接delete (select User ...).<author[is Review]——括号里是一个合法的集合表达式。
  • 语句执行成功后,返回被删除对象的集合。

在 docs/reference/edgeql/delete.rst 中可以看到带全部子句的完整示例:

delete Hero filter .name ilike 'the %' order by .name offset 10 limit 5;

该示例先按名字模糊过滤,再排序、跳过前 10 条、最多删除 5 条——相当于一次"分批清理"。

删除与 select 的等价关系(源码佐证)

deletedelete (select ...)的语法糖这一点,在仓库测试 tests/test_edgeql_delete.py 的test_edgeql_delete_sugar_01(第 378 行起)中有直接验证:

DELETE DeleteTest FILTER .name[-1] != '2' ORDER BY .name OFFSET 2 LIMIT 2; # should delete 4 and 5

测试先插入 6 条名为'sugar delete 1''sugar delete 6'的记录,然后执行带filter/order by/offset/limit的删除,最后断言只剩'sugar delete 1''sugar delete 2''sugar delete 3''sugar delete 6'——即OFFSET 2 LIMIT 2精准删掉了排序后的第 4、5 条。这说明排序与分页子句确实作用于"被删除集合"的成型过程,与select行为一致。

同文件中还有test_edgeql_delete_returning_01_05test_edgeql_delete_uniontest_edgeql_delete_multi_simultaneous_01等用例,覆盖了删除返回值、并集删除、多对象同时删除等场景,是深入学习delete行为的第一手材料。

删除返回值:数据永久消失前的最后一刻

delete返回被删除对象的集合,你可以把它继续交给select,在数据被永久删除前取出其属性与链接:

with movie := (delete Movie filter .title = "Untitled") select movie {id, title};

正如 docs/reference/edgeql/delete.rst 中所强调:这是该数据在永久删除前最后一次可用的时机。常见的实用模式包括:删除前把对象快照归档到审计表、统计本次删除了多少条、或把被删对象的 id 记录下来用于后续补偿逻辑。测试文件中的test_edgeql_delete_returning_*系列用例(如test_edgeql_delete_returning_01,tests/test_edgeql_delete.py 第 179 行)专门验证了这种"删除后立即 select"的返回行为。

链接删除策略:为什么删除会被拒绝

默认情况下,你不能删除一个仍被其它对象链接引用的对象。例如:

db> delete Hero filter .name = "Yelena Belova"; ConstraintViolationError: deletion of default::Hero (af7076e0-3e98-11ec-abb3-b3435bbe7c7e) is prohibited by link target policy {}

这个报错发生的原因是 Yelena 仍出现在《黑寡妇》电影的characters链接列表中。必须先解除这条链接,再执行删除:

update Movie filter .title = "Black Widow" set { characters -= (select Hero filter .name = "Yelena Belova") }; delete Hero filter .name = "Yelena Belova";

这与 Cheatsheet 范式二"先取出反向链接集合再删除"的思路互为补充:范式二是直接对反向链接集合执行删除,而这里先用-=把链接从源对象上移除,再删除目标对象。

如果业务上允许"删目标时自动断开链接",可以在 schema 中把链接的删除策略改为on target delete allow

type Movie { required title: str { constraint exclusive }; required release_year: int64; multi characters: Person { on target delete allow; }; }

删除策略的完整清单见 docs/reference/datamodel/links.rst(ref_datamodel_link_deletion一节)。

级联删除:delete source 与 delete target

链接的删除策略不仅限于"禁止/放行":

  • 默认策略:禁止删除仍被引用的目标对象(上述报错即源于此);
  • on target delete allow:允许删除目标对象,链接随之消失;
  • on target delete delete source:删除目标对象时,连带删除链接的源对象——这就是级联删除(cascading delete)的实现方式,例如删除作者时同时删掉他写的所有评论;
  • on target delete restrict:更加严格的限制。

对应的还有on source delete相关策略。正如 docs/reference/edgeql/delete.rst 中的提醒:级联删除能力强大,使用时要格外谨慎,一个delete可能波及一整条对象链。建议在投入生产前,先在测试环境用delete的返回集合确认实际波及范围。

总结与推荐阅读

回到 Cheatsheet 的两行速查:

-- 范式一:按链接路径过滤 delete Review filter .author.name = 'trouble2020' -- 范式二:反向链接 + 类型过滤 delete ( select User filter .name = 'troll2020' ).<author[is Review]

两者结果等价,但表达路径不同:范式一从"被删对象"出发正向过滤,范式二从"根对象"出发反向遍历。实际项目中,前者适合"按条件批量清理某类对象",后者适合"删除某对象的全部关联"。

如果希望进一步深入,推荐按以下顺序阅读仓库内材料:

  • docs/resources/cheatsheets/objects.rst:本文示例所用的User/Review/Movie完整 schema 定义;
  • docs/reference/edgeql/delete.rst:delete的全面行为说明(链接删除策略、级联、返回值);
  • docs/reference/reference/edgeql/delete.rst:语句的正式语法与delete (select ...)等价关系;
  • tests/test_edgeql_delete.py:覆盖语法糖、返回值、并集删除、多对象同时删除等场景的测试用例,是验证本文所有结论的最直接依据。

【免费下载链接】edgedbGel supercharges Postgres with a modern data model, graph queries, Auth & AI solutions, and much more.项目地址: https://gitcode.com/gh_mirrors/ed/edgedb

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 11:19:55

校园心理健康咨询平台开发实践:微信小程序与PHP技术解析

1. 项目概述&#xff1a;校园心理健康咨询平台的设计初衷大学生群体面临学业压力、人际关系、就业焦虑等多重心理挑战&#xff0c;传统线下心理咨询存在预约难、隐私顾虑等问题。我们团队基于微信小程序和PHP开发了一套校园心理健康咨询平台&#xff0c;实现心理测评、在线咨询…

作者头像 李华
网站建设 2026/9/23 11:18:55

本地部署星辰Xing4.0-29B:MoE架构下的AI表格与文档助手实战

开源大模型这段时间是真的热闹&#xff0c;各个团队轮番放新东西&#xff0c;但真能让人踏踏实实跑在本地、干实际工作的&#xff0c;其实没那么多。我拿到中国电信星辰Xing4.0-29B这个开源版本之后&#xff0c;第一时间就在自己的机器上部署了一轮&#xff0c;重点测了两个高频…

作者头像 李华
网站建设 2026/9/23 11:16:12

蛋白粉营养头部公司的核心竞争力与产业发展探析

一、蛋白粉营养赛道与头部公司核心特质伴随国民健康认知升级&#xff0c;蛋白质膳食补充需求持续释放&#xff0c;蛋白粉作为蛋白营养赛道核心产品&#xff0c;应用场景从专业健身拓展至产后营养、中老年膳食补充、日常体质管理等多元领域。蛋白粉依托乳清蛋白、酪蛋白、植物蛋…

作者头像 李华
网站建设 2026/9/23 11:14:32

DIE查壳工具实战指南:识别加壳程序与批量扫描

简介&#xff1a;DIE&#xff08;Detect It Easy&#xff09;是一款专业查壳工具&#xff0c;主要面向安全分析、逆向工程与恶意代码检测场景&#xff0c;可快速识别程序加壳类型、编译语言及打包器特征&#xff0c;并支持超大文件读取&#xff0c;相比PEID在复杂程序检测上更具…

作者头像 李华
网站建设 2026/9/23 11:13:08

GEO生成式引擎优化:从SEO到RAG知识库的范式转移与实操指南

1. GEO到底是什么&#xff1a;从SEO到生成式引擎优化的范式转移1.1 一个正在发生的流量入口迁移做了十几年SEO的人&#xff0c;最近两年应该都有一个明显的体感&#xff1a;传统搜索引擎的流量在肉眼可见地下滑。不是搜索引擎本身没人用了&#xff0c;而是用户获取信息的方式变…

作者头像 李华