SeaORM 与 Seaography 实战:用 Rust 从数据库一键生成 GraphQL API

发布时间:2026/9/24 16:11:32

SeaORM 与 Seaography 实战:用 Rust 从数据库一键生成 GraphQL API 后端数据库ORM【免费下载链接】sea-orm A powerful relational ORM for Rust项目地址https://gitcode.com/gh_mirrors/se/sea-orm点击查看免费下载导读本文基于 SeaORM 仓库中的 seaography_example 完整示例系统讲解如何将 SeaORM 实体模型与 Seaography 结合从现有数据库Bakery 面包店 Schema一键生成可运行的 GraphQL API 服务。你将掌握如何初始化数据库并运行迁移、如何安装sea-orm-cli与seaography-cli两条 CLI 工具链、如何用代码生成器产出 GraphQL 工程以及如何在 GraphQL Playground 中编写筛选、聚合与多级关联查询。读完本文你可以在自己的 Rust 项目中复刻数据库 → 实体 → GraphQL 服务的完整流水线。示例概览Bakery 面包店 Schema整个示例围绕一个面包店业务模型展开涉及 6 张业务表与 1 张多对多关联表仓库中已经包含了迁移定义、种子数据与已生成的 SQLite 数据库文件bakery.db。核心实体及其关系如下bakery面包店id、name、profit_margin拥有多个bakers与多个cakesbaker面包师id、name、contact、bakery_id可空通过cake_baker与cakes多对多关联cake蛋糕id、name、priceDecimal、bakery_id、gluten_free通过cake_baker与bakers多对多关联cake_baker关联表cake_idbaker_id复合主键用于表达蛋糕由哪些面包师制作customer、order、lineitem顾客、订单与订单行明细构成完整的零售业务链路。从生成的实体代码可以看到 SeaORM 的关系定义方式cake.rs#[sea_orm::model] #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] #[sea_orm(table_name cake)] pub struct Model { #[sea_orm(primary_key)] pub id: i32, pub name: String, #[sea_orm(column_type Decimal(Some((16, 4))))] pub price: Decimal, pub bakery_id: i32, pub gluten_free: bool, #[sea_orm( belongs_to, from bakery_id, to id, on_update Cascade, on_delete Cascade )] pub bakery: BelongsTosuper::bakery::Entity, #[sea_orm(has_many, via cake_baker)] pub bakers: HasManysuper::baker::Entity, } impl ActiveModelBehavior for ActiveModel {}正是这些belongs_to/has_many/has_many(via ...)声明让 Seaography 在构建 GraphQL Schema 时能够自动推导出可嵌套查询的对象关系。运行示例项目1. 指定数据库连接示例默认使用 SQLite 数据库通过环境变量DATABASE_URL指定连接地址。仓库已自带bakery.db直接用只读模式连接即可export DATABASE_URLsqlite://../bakery.db连接 URL 基于graphql目录解析因此../bakery.db指向示例根目录下的数据库文件。若希望以读写模式打开例如用于后续重新跑迁移可改为export DATABASE_URLsqlite://../bakery.db?moderwc2. 启动 GraphQL 服务进入生成好的 GraphQL 工程并直接运行cd graphql cargo run服务启动入口位于 main.rs它通过sea-orm的Database::connect建立连接然后调用query_root::schema构建 Schema最后用axum在默认地址localhost:8000暴露 GraphQL 端点let db Database::connect(*DATABASE_URL) .await .expect(Fail to initialize database connection); let schema sea_orm_seaography_example::query_root::schema(db, *DEPTH_LIMIT, *COMPLEXITY_LIMIT) .unwrap(); let app Router::new() .route(*ENDPOINT, get(graphql_playground).post(graphql_handler)) .with_state(schema); println!(Visit GraphQL Playground at http://{}, *URL); axum::serve(TcpListener::bind(*URL).await.unwrap(), app) .await .unwrap();这里还支持三个可选环境变量均用于 GraphQL 服务的运行期控制环境变量默认值作用URLlocalhost:8000服务监听地址浏览器访问 GraphQL Playground 的入口ENDPOINT/GraphQL 端点路径Playground 与查询请求都挂在它下面DEPTH_LIMIT不限制限制查询嵌套深度防止恶意深嵌套查询COMPLEXITY_LIMIT不限制限制单次查询的复杂度保护后端数据库启动后打开http://localhost:8000即可看到 GraphQL Playground 界面本示例开启了graphql-playgroundfeature。运行示例中的 GraphQL 查询Seaography 为每个实体自动生成对应的根查询字段同时内置了filters过滤、having聚合后过滤、orderBy排序、pagination分页等标准入参。下面三个查询与文档一致可在 Playground 中直接执行验证。查询 1查找巧克力蛋糕及其在售面包店{ cake(filters: { name: { contains: Chocolate } }) { nodes { name price bakery { name } } } }filters支持字符串的contains包含、eq等于、startsWith、endsWith等运算返回结果通过nodes承载数据行并可沿cake - bakery的 belongs_to 关系继续取面包店名称。该查询在仓库测试 query_tests.rs 中被完整断言过预期结果包含 SeaSide Bakery 的两款巧克力蛋糕与 LakeSide Bakery 的一款例如{ cake: { nodes: [ { name: Chocolate Cake, price: 10.25, bakery: { name: SeaSide Bakery } }, { name: Double Chocolate, price: 12.5, bakery: { name: SeaSide Bakery } }, { name: Double Chocolate, price: 12.5, bakery: { name: LakeSide Bakery } } ] } }查询 2查找 Alice 烘焙的所有蛋糕{ cake(having: { baker: { name: { eq: Alice } } }) { nodes { name price baker { nodes { name } } } } }having用于按关联实体条件筛选聚合结果这里要求目标蛋糕必须存在名为Alice的关联面包师经由多对多表cake_baker。值得注意的是外层cake与内层baker的返回结构不同——cake.baker是多对多关系因此以nodes列表形式返回而查询 1 中cake.bakery属于一对一belongs_to关系直接返回对象即可。查询 3面包店 → 蛋糕 → 面包师三级嵌套{ bakery(pagination: { page: { limit: 10, page: 0 } }, orderBy: { name: ASC }) { nodes { name cake { nodes { name price baker { nodes { name } } } } } } }这个查询同时演示了pagination每页 10 条、第 0 页与orderBy按名称升序两种入参并沿bakery - cake - baker三级关系嵌套取数充分体现 Seaography 将 SeaORM 关系模型直接映射为 GraphQL 对象图的能力。注意分页入参中page字段被复用了两次外层为分页对象、内层page为页码使用时需区分。从零搭建完整的生成流程如果不使用仓库自带的生成结果可以按下面四步从头搭建一个属于自己的 SeaORM Seaography GraphQL 工程。第一步准备数据库与迁移进入migration目录其 README 提供了完整说明。设置数据库并应用全部迁移export DATABASE_URLsqlite://../bakery.db?moderwc cd migration cargo run迁移工程包含 7 个迁移文件migration/src从建表到播种依次执行m20230101_000001_create_bakery_table.rs创建bakery表m20230101_000002_create_baker_table.rs创建baker表m20230101_000003_create_cake_table.rs创建cake表m20230101_000004_create_cake_baker_table.rs创建多对多关联表cake_bakerm20230101_000005_create_customer_table.rs创建customer表m20230101_000006_create_order_table.rs创建order表m20230101_000007_create_lineitem_table.rs创建lineitem表m20230102_000001_seed_bakery_data.rs向表中写入 SeaSide Bakery、LakeSide Bakery、Alice、Bob 及各款蛋糕等演示数据。建表迁移使用 SeaORM Migration 的声明式 API例如创建bakery表m20230101_000001_create_bakery_table.rsmanager .create_table( Table::create() .table(bakery) .col(pk_auto(id)) .col(string(name)) .col(double(profit_margin)) .to_owned(), ) .await种子迁移则通过 ActiveModel 插入数据m20230102_000001_seed_bakery_data.rslet bakery bakery::ActiveModel { name: Set(SeaSide Bakery.to_owned()), profit_margin: Set(10.4), ..Default::default() }; let sea Bakery::insert(bakery).exec(db).await?.last_insert_id;迁移 CLI 还支持常用子命令方便管理 Schema 演进命令作用cargo run/cargo run -- up应用所有待执行迁移cargo run -- up -n 10仅应用前 10 个迁移cargo run -- down回滚最近一次迁移cargo run -- down -n 10回滚最近 10 次迁移cargo run -- fresh先删库重建再全部重跑cargo run -- refresh回滚全部后重新应用全部迁移cargo run -- reset回滚全部迁移cargo run -- status查看各迁移执行状态第二步安装两条 CLI 工具链SeaORM Seaography 的代码生成依赖两个 CLI建议使用 2.0 系列的预发布版本cargo install sea-orm-cli^2.0.0-rc cargo install seaography-cli^2.0.0-rcsea-orm-cli负责从数据库反向生成 SeaORM 实体代码seaography-cli负责基于已生成的实体搭建完整的 GraphQL 服务工程axum 框架 async-graphql。第三步生成实体与 GraphQL 工程rm -rf graphql # this entire folder is generated mkdir graphql cd graphql sea-orm-cli generate entity --output-dir ./src/entities --entity-format dense --seaography seaography-cli -o . -e ./src/entities --framework axum sea-orm-seaography-example命令逐条说明sea-orm-cli generate entity连接DATABASE_URL指向的数据库并生成实体--output-dir ./src/entities指定实体输出目录--entity-format dense采用紧凑的实体代码风格--seaography是关键开关它让生成的实体额外携带 Seaography 所需的元数据与关系定义seaography-cli -o . -e ./src/entities --framework axum sea-orm-seaography-example以实体目录为输入生成名为sea-orm-seaography-example的 GraphQL 工程到当前目录Web 框架选择 axum。生成的工程结构与仓库中 graphql 目录一致包括src/entities/从数据库反向生成的 SeaORM 实体baker、bakery、cake、cake_baker 等含mod.rs与prelude.rssrc/query_root.rsSchema 构建逻辑负责把全部实体注册进 GraphQL 并配置深度/复杂度限制src/main.rsaxum 服务入口暴露 Playground 与 GraphQL 端点Cargo.toml依赖配置其中sea-orm开启seaographyfeatureseaography按需开启graphql-playground、with-decimal、with-chrono等特性。query_root.rs是理解生成代码的关键query_root.rspub fn schema_builder( context: static BuilderContext, database: DatabaseConnection, depth: Optionusize, complexity: Optionusize, ) - SchemaBuilder { let mut builder Builder::new(context, database.clone()); builder register_entity_modules(builder); builder .set_depth_limit(depth) .set_complexity_limit(complexity) .schema_builder() .data(database) }从源码结构可以推断Builder遍历所有注册的实体模块把每个实体的查询入口、过滤参数、分页与排序参数以及实体间关系统一翻译成 async-graphql 的动态 Schemaset_depth_limit与set_complexity_limit则把上文的环境变量注入查询保护策略。第四步在自己的工程中调整依赖生成后的Cargo.toml依赖大致如下版本以当前仓库为准[dependencies.sea-orm] features [sqlx-sqlite, runtime-tokio-native-tls, seaography] version ~2.0.3 [dependencies.seaography] features [graphql-playground, with-decimal, with-chrono] version ~2.0.0-rc.3 [dependencies] async-graphql-axum { version 7.0 } axum { version 0.8 } dotenv 0.15.0 tokio { version 1.29.1, features [macros, rt-multi-thread] }几点实战提示sea-orm必须开启seaographyfeature否则query_root.rs依赖的实体注册 API 不可用数据库驱动 feature 要与实际使用的数据库匹配示例中使用 SQLitesqlx-sqliteMySQL/PostgreSQL 项目需相应替换若实体包含Decimal或时间类型字段建议开启with-decimal与with-chrono保证 GraphQL 标量序列化正确本示例的cake.price正是 Decimal 类型查询结果中价格以字符串形式返回如10.25示例中[patch.crates-io] sea-orm { path ../../.. }用于在仓库内联调 SeaORM 本体自己新建工程时应删除该行直接使用 crates.io 发布的版本。验证与测试生成工程自带集成测试可直接验证 GraphQL Schema 与查询结果是否符合预期cd graphql DATABASE_URLsqlite://../bakery.db cargo test测试用例位于 query_tests.rs覆盖了文档中的典型查询test_cake_with_bakery按name.contains(Chocolate)过滤并嵌套取面包店信息test_cake_with_baker按关联面包师姓名过滤以及多级嵌套与排序分页场景。测试内部通过sea_orm::Database::connect连接数据库再调用query_root::schema构建 Schema 后直接executeGraphQL 请求将返回结果与期望 JSON 逐字段比对。这套测试结构可以直接复制到自己的工程中作为 GraphQL API 的回归保障。小结通过本示例可以清晰看到 SeaORM 生态中数据访问层 GraphQL 层的完整协同方式SeaORM 负责用 Rust 类型安全地描述数据库表与关系sea-orm-cli将数据库结构反向生成为实体seaography-cli再把实体工程升级为开箱即用的 GraphQL 服务。整条链路从bakery.db出发几分钟内即可得到支持过滤、排序、分页与多级嵌套查询的 GraphQL API非常适合作为Rust 全栈 GraphQL项目的起步模板。后续可在此基础上继续扩展更换 MySQL/PostgreSQL 驱动、接入认证授权中间件或调整DEPTH_LIMIT/COMPLEXITY_LIMIT以适配更复杂的查询场景。赞分享后端数据库ORM【免费下载链接】sea-orm A powerful relational ORM for Rust项目地址https://gitcode.com/gh_mirrors/se/sea-orm点击查看免费下载相关推荐MovieNight常见问题解决流媒体卡顿、聊天连接失败与权限问题排查MovieNight常见问题解决流媒体卡顿、聊天连接失败与权限问题排查 MovieNight是一款集成聊天功能的单实例视频流媒体服务器专为在线观影群体设计。SeaORM 实战基于 Loco 与 Seaography 的 GraphQL 管理后台——react-admin 示例全解析SeaORM 实战基于 Loco 与 Seaography 的 GraphQL 管理后台——react admin 示例全解析 本篇文章以 sea orm 仓后端数据库ORMNocoBase CLI nb env remove 深度解析安全移除已配置环境与清理本机托管资源NocoBase CLI nb env remove 深度解析安全移除已配置环境与清理本机托管资源 NocoBase CLI nb 通过 env环境机后端数据库ORM上一篇AutoSubs终极指南如何在本地设备上实现专业级AI字幕生成下一篇OpenDesign Airtable 设计系统深度解析从 DESIGN 规范到 tokens.css 的落地实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/24 16:11:32

无意识稳住血糖的5个小习惯

#现在到处都是控糖#有些不经意的行为,能帮你在不知不觉中稳住血糖↓↓【吃饭爱加点醋】醋可以延缓胃排空速度,促进血液中葡萄糖的消耗。还能抑制淀粉酶活性,降低碳水化合物的消化速率,延缓小肠对葡萄糖的吸收。【吃新鲜水果而不是…

2026/9/24 16:06:32

codewhale web 上手指南:一条命令把终端 Agent 搬进浏览器

codewhale web 上手指南:一条命令把终端 Agent 搬进浏览器 【免费下载链接】Codewhale Open-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome. 项目地址: https://gitcode.…

2026/9/24 17:06:39

Windows 跑 Codex:原生 PowerShell 还是 WSL2?仓库放错最容易踩坑

Windows 跑 Codex:原生 PowerShell 还是 WSL2?仓库放错最容易踩坑 [!NOTE] Windows 版 ChatGPT 桌面应用默认使用 Windows 原生 Codex Agent,并在 PowerShell 环境运行;也可以把 Agent 切换到 WSL2。 “Agent 在哪里运行”“集成终端显示什么”“仓库实际存在哪个文件系统”…

2026/9/24 17:06:39

一个项目挂 3 个仓库:Codex 多文件夹项目与跨仓 Diff 怎么审

一个项目挂 3 个仓库:Codex 多文件夹项目与跨仓 Diff 怎么审 [!NOTE] ChatGPT 桌面应用的本地 Project 可以附加多个文件夹,并指定一个 Primary folder;Codex 能读写所有附加目录,但自动发现 AGENTS.md、Skills、config.toml 和默认 Git 操作仍以主目录为中心。 Review pan…

2026/9/23 12:07:00

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/24 0:00:21

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:21

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:21

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码