SeaQL/sea-orm

GitHub: SeaQL/sea-orm

SeaORM 是一个功能完善的 Rust 异步 ORM 框架,提供实体关联建模、智能查询加载、数据库迁移和嵌套持久化等特性,帮助开发者高效构建数据库驱动的应用。

Stars: 9500 | Forks: 692

SeaORM

SeaORM 是一个强大的 ORM,用于在 Rust 中构建 Web 服务

[![crate](https://img.shields.io/crates/v/sea-orm.svg)](https://crates.io/crates/sea-orm) [![build status](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/bbbf12b426004834.svg)](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml) [![GitHub stars](https://img.shields.io/github/stars/SeaQL/sea-orm.svg?style=social&label=Star&maxAge=1)](https://github.com/SeaQL/sea-orm/stargazers/)
请给我们一个 ⭐ 支持我们!
# 🐚 SeaORM [中文文档](https://github.com/SeaQL/sea-orm/blob/master/README-zh.md) ### 高级关联 以高级、概念性的方式对 1-1、1-N、M-N 甚至自引用的复杂关系进行建模。 ### 熟悉的概念 受到 Ruby、Python 和 Node.js 生态系统中流行的 ORM 启发,SeaORM 提供了一种让人倍感亲切的开发者体验。 ### 功能丰富 SeaORM 是一个功能齐全的 ORM,包含过滤器、分页和嵌套查询,以加速构建 REST、GraphQL 和 gRPC API。 ### 生产就绪 拥有超过 25 万的周下载量,SeaORM 已准备好投入生产,并受到全球初创公司和企业的信赖。 ## 快速入门 [![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv) 加入我们的 Discord 服务器与其他人交流! + [文档](https://www.sea-ql.org/SeaORM) 集成示例: + [Actix Example](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example) + [Axum Example](https://github.com/SeaQL/sea-orm/tree/master/examples/axum_example) + [GraphQL Example](https://github.com/SeaQL/sea-orm/tree/master/examples/graphql_example) + [jsonrpsee Example](https://github.com/SeaQL/sea-orm/tree/master/examples/jsonrpsee_example) + [Loco Example](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_example) / [Loco REST Starter](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_starter) + [Poem Example](https://github.com/SeaQL/sea-orm/tree/master/examples/poem_example) + [Rocket Example](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_example) / [Rocket OpenAPI Example](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_okapi_example) + [Salvo Example](https://github.com/SeaQL/sea-orm/tree/master/examples/salvo_example) + [Tonic Example](https://github.com/SeaQL/sea-orm/tree/master/examples/tonic_example) + [Seaography Example (Bakery)](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) / [Seaography Example (Sakila)](https://github.com/SeaQL/seaography/tree/main/examples/sqlite) 如果你想要一个简单、整洁且适合单文件的示例来展示 SeaORM 的精华,你可以尝试: + [Quickstart](https://github.com/SeaQL/sea-orm/blob/master/examples/quickstart/src/main.rs) 让我们快速浏览一下 SeaORM 的独特功能。 ## 表达性的实体格式 你不必手动编写这些!可以使用 `sea-orm-cli` 从现有数据库生成实体文件, 以下是用 `--entity-format dense` 生成的 *(2.0 新增)*。 ``` mod user { use sea_orm::entity::prelude::*; #[sea_orm::model] #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] #[sea_orm(table_name = "user")] pub struct Model { #[sea_orm(primary_key)] pub id: i32, pub name: String, #[sea_orm(unique)] pub email: String, #[sea_orm(has_one)] pub profile: HasOne, #[sea_orm(has_many)] pub posts: HasMany, } } mod post { use sea_orm::entity::prelude::*; #[sea_orm::model] #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] #[sea_orm(table_name = "post")] pub struct Model { #[sea_orm(primary_key)] pub id: i32, pub user_id: i32, pub title: String, #[sea_orm(belongs_to, from = "user_id", to = "id")] pub author: HasOne, #[sea_orm(has_many, via = "post_tag")] // M-N relation with junction pub tags: HasMany, } } ``` ## 智能实体加载器 实体加载器智能地对 1-1 关系使用 join,对 1-N 关系使用数据加载器, 即使在执行嵌套查询时也能消除 N+1 问题。 ``` // join paths: // user -> profile // user -> post // post -> post_tag -> tag let smart_user = user::Entity::load() .filter_by_id(42) // shorthand for .filter(user::COLUMN.id.eq(42)) .with(profile::Entity) // 1-1 uses join .with((post::Entity, tag::Entity)) // 1-N uses data loader .one(db) .await? .unwrap(); // 3 queries are executed under the hood: // 1. SELECT FROM user JOIN profile WHERE id = $ // 2. SELECT FROM post WHERE user_id IN (..) // 3. SELECT FROM tag JOIN post_tag WHERE post_id IN (..) smart_user == user::ModelEx { id: 42, name: "Bob".into(), email: "bob@sea-ql.org".into(), profile: HasOne::Loaded( profile::ModelEx { picture: "image.jpg".into(), } .into(), ), posts: HasMany::Loaded(vec![post::ModelEx { title: "Nice weather".into(), tags: HasMany::Loaded(vec![tag::ModelEx { tag: "sunny".into(), }]), }]), }; ``` ## ActiveModel:简化嵌套持久化 使用流式构建器 API 在单个操作中持久化整个对象图:用户、资料 (1-1)、帖子 (1-N) 和标签 (M-N)。 SeaORM 会自动确定依赖关系,并按正确的顺序插入或删除对象。 ``` // this creates the nested object as shown above: let user = user::ActiveModel::builder() .set_name("Bob") .set_email("bob@sea-ql.org") .set_profile(profile::ActiveModel::builder().set_picture("image.jpg")) .add_post( post::ActiveModel::builder() .set_title("Nice weather") .add_tag(tag::ActiveModel::builder().set_tag("sunny")), ) .save(db) .await?; ``` ## Schema 优先还是 Entity 优先?由你选择 SeaORM 提供了一个强大的迁移系统,让你可以轻松创建表、修改 schema 和填充数据。 在 SeaORM 2.0 中,你还获得了[实体优先工作流 (Entity First Workflow)](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/): 只需定义新实体或向现有实体添加列, SeaORM 将自动检测更改并创建新表、列、唯一键和外键。 ``` // SeaORM resolves foreign key dependencies and creates the tables in topological order. // Requires the `entity-registry` and `schema-sync` feature flags. db.get_schema_registry("my_crate::entity::*").sync(db).await; ``` ## 符合人体工学的原生 SQL 让 SeaORM 处理你 95% 的事务性查询。 对于剩余那些过于复杂而无法表达的情况, SeaORM 仍然为编写原生 SQL 提供了便捷的支持。 ``` let user = Item { name: "Bob" }; // nested parameter access let ids = [2, 3, 4]; // expanded by the `..` operator let user: Option = user::Entity::find() .from_raw_sql(raw_sql!( Sqlite, r#"SELECT "id", "name" FROM "user" WHERE "name" LIKE {user.name} AND "id" in ({..ids}) "# )) .one(db) .await?; ``` ## 同步支持 [`sea-orm-sync`](https://crates.io/crates/sea-orm-sync) 提供了完整的 SeaORM API,无需异步运行时,非常适合使用 SQLite 的轻量级 CLI 程序。 有关用法,请参阅 [quickstart example](https://github.com/SeaQL/sea-orm/blob/master/sea-orm-sync/examples/quickstart/src/main.rs)。 ## 基础 ### Select SeaORM 在实体级别对 1-N 和 M-N 关系进行建模, 让你可以通过连接表在单次调用中遍历多对多链接。 ``` // find all models let cakes: Vec = Cake::find().all(db).await?; // find and filter let chocolate: Vec = Cake::find() .filter(Cake::COLUMN.name.contains("chocolate")) .all(db) .await?; // find one model let cheese: Option = Cake::find_by_id(1).one(db).await?; let cheese: cake::Model = cheese.unwrap(); // find related models (lazy) let fruit: Option = cheese.find_related(Fruit).one(db).await?; // find related models (eager): for 1-1 relations let cake_with_fruit: Vec<(cake::Model, Option)> = Cake::find().find_also_related(Fruit).all(db).await?; // find related models (eager): works for both 1-N and M-N relations let cake_with_fillings: Vec<(cake::Model, Vec)> = Cake::find() .find_with_related(Filling) // for M-N relations, two joins are performed .all(db) // rows are automatically consolidated by left entity .await?; ``` ### 嵌套 Select 部分模型只允许查询所需的字段,从而防止过度获取;这也使得编写深度嵌套的关系查询变得简单。 ``` use sea_orm::DerivePartialModel; #[derive(DerivePartialModel)] #[sea_orm(entity = "cake::Entity")] struct CakeWithFruit { id: i32, name: String, #[sea_orm(nested)] fruit: Option, // this can be a regular or another partial model } let cakes: Vec = Cake::find() .left_join(fruit::Entity) // no need to specify join condition .into_partial_model() // only the columns in the partial model will be selected .all(db) .await?; ``` ### Insert SeaORM 的 ActiveModel 让你可以直接使用 Rust 数据结构, 并通过简单的 API 持久化它们。 从不同数据源插入大批量行数据非常容易。 ``` let apple = fruit::ActiveModel { name: Set("Apple".to_owned()), ..Default::default() // no need to set primary key }; let pear = fruit::ActiveModel { name: Set("Pear".to_owned()), ..Default::default() }; // insert one: Active Record style let apple = apple.insert(db).await?; apple.id == 1; // insert one: repository style let result = Fruit::insert(apple).exec(db).await?; result.last_insert_id == 1; // insert many returning last insert id let result = Fruit::insert_many([apple, pear]).exec(db).await?; result.last_insert_id == Some(2); ``` ### Insert (进阶) 你可以利用数据库的特定功能来执行 upsert 和幂等插入。 ``` // insert many with returning (if supported by database) let models: Vec = Fruit::insert_many([apple, pear]) .exec_with_returning(db) .await?; models[0] == fruit::Model { id: 1, // database assigned value name: "Apple".to_owned(), cake_id: None, }; // insert with ON CONFLICT on primary key do nothing, with MySQL specific polyfill let result = Fruit::insert_many([apple, pear]) .on_conflict_do_nothing() .exec(db) .await?; matches!(result, TryInsertResult::Conflicted); ``` ### Update ActiveModel 仅更新你更改的字段,从不覆盖未触碰的列,从而避免竞争条件。 你还可以使用流式查询构建 API 构建复杂的批量更新查询。 ``` use sea_orm::sea_query::{Expr, Value}; let pear: Option = Fruit::find_by_id(1).one(db).await?; let mut pear: fruit::ActiveModel = pear.unwrap().into(); pear.name = Set("Sweet pear".to_owned()); // update value of a single field // update one: only changed columns will be updated let pear: fruit::Model = pear.update(db).await?; // update many: UPDATE "fruit" SET "cake_id" = "cake_id" + 2 // WHERE "fruit"."name" LIKE '%Apple%' Fruit::update_many() .col_expr(fruit::COLUMN.cake_id, fruit::COLUMN.cake_id.add(2)) .filter(fruit::COLUMN.name.contains("Apple")) .exec(db) .await?; ``` ### Save 你可以使用 ActiveModel 执行“插入或更新”操作,从而轻松组合事务性操作。 ``` let banana = fruit::ActiveModel { id: NotSet, name: Set("Banana".to_owned()), ..Default::default() }; // create, because primary key `id` is `NotSet` let mut banana = banana.save(db).await?; banana.id == Unchanged(2); banana.name = Set("Banana Mongo".to_owned()); // update, because primary key `id` is present let banana = banana.save(db).await?; ``` ### Delete 与 insert 和 update 保持一致的 ActiveModel API。 ``` // delete one: Active Record style let orange: Option = Fruit::find_by_id(1).one(db).await?; let orange: fruit::Model = orange.unwrap(); orange.delete(db).await?; // delete one: repository style let orange = fruit::ActiveModel { id: Set(2), ..Default::default() }; fruit::Entity::delete(orange).exec(db).await?; // delete many: DELETE FROM "fruit" WHERE "fruit"."name" LIKE '%Orange%' fruit::Entity::delete_many() .filter(fruit::COLUMN.name.contains("Orange")) .exec(db) .await?; ``` ### 原生 SQL 查询 `raw_sql!` 宏类似于 `format!` 宏,但没有 SQL 注入的风险。 它支持嵌套参数插值、数组和元组扩展,甚至重复分组, 为编写复杂查询提供了极大的灵活性。 ``` #[derive(FromQueryResult)] struct CakeWithBakery { name: String, #[sea_orm(nested)] bakery: Option, } #[derive(FromQueryResult)] struct Bakery { #[sea_orm(alias = "bakery_name")] name: String, } let cake_ids = [2, 3, 4]; // expanded by the `..` operator // can use many APIs with raw SQL, including nested select let cake: Option = CakeWithBakery::find_by_statement(raw_sql!( Sqlite, r#"SELECT "cake"."name", "bakery"."name" AS "bakery_name" FROM "cake" LEFT JOIN "bakery" ON "cake"."bakery_id" = "bakery"."id" WHERE "cake"."id" IN ({..cake_ids})"# )) .one(db) .await?; ``` ## 🧭 Seaography:即时 GraphQL API [Seaography](https://github.com/SeaQL/seaography) 是为 SeaORM 构建的 GraphQL 框架。 Seaography 允许你快速构建 GraphQL 解析器。 只需几条命令,你就可以从 SeaORM 实体启动一个功能齐全的 GraphQL 服务器, 完整支持过滤、分页、关系查询和变更! 查看 [Seaography Example](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) 以了解更多信息。 ## 🖥️ SeaORM Pro:专业管理面板 [SeaORM Pro](https://github.com/SeaQL/sea-orm-pro/) 是一个管理面板解决方案,让你可以快速轻松地为应用程序启动管理面板 —— 不需要前端开发技能,但有的话当然更好! SeaORM Pro 已更新以支持 SeaORM 2.0 的最新功能。 功能: + 完整的 CRUD + 基于 React + GraphQL 构建 + 内置 GraphQL 解析器 + 使用 TOML 配置自定义 UI + 基于角色的访问控制 *(2.0 新增)* 阅读 [Getting Started](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started/) 指南以了解更多信息。 ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/c59e0af1f4004836.png) ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/c664cbcc9d004839.png) ## SQL Server 支持 [SQL Server for SeaORM](https://www.sea-ql.org/SeaORM-X/) 为 MSSQL 提供相同的 SeaORM API。我们移植了所有测试用例和示例,并补充了 MSSQL 特定的文档。如果你正在构建企业软件,可以[申请商业访问权限](https://forms.office.com/r/1MuRPJmYBR)。它目前基于 SeaORM 1.0,但当 SeaORM 2.0 正式发布时,我们将为现有用户提供免费升级。 ## 版本发布 SeaORM 2.0 已进入候选发布阶段。我们希望你能试用它,并通过[分享你的反馈](https://github.com/SeaQL/sea-orm/discussions/)来帮助塑造最终版本。 + [Change Log](https://github.com/SeaQL/sea-orm/tree/master/CHANGELOG.md) SeaORM 2.0 正在成为我们最重要的版本 —— 包含一些破坏性更改、大量增强功能,并明确专注于开发者体验。 + [A Sneak Peek at SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-16-sea-orm-2.0/) + [SeaORM 2.0: A closer look](https://www.sea-ql.org/blog/2025-09-24-sea-orm-2.0/) + [Role Based Access Control in SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-30-sea-orm-rbac/) + [Seaography 2.0: A Powerful and Extensible GraphQL Framework](https://www.sea-ql.org/blog/2025-10-08-seaography/) + [SeaORM 2.0: New Entity Format](https://www.sea-ql.org/blog/2025-10-20-sea-orm-2.0/) + [SeaORM 2.0: Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/) + [SeaORM 2.0: Strongly-Typed Column](https://www.sea-ql.org/blog/2025-11-11-sea-orm-2.0/) + [What's new in SeaORM Pro 2.0](https://www.sea-ql.org/blog/2025-11-21-whats-new-in-seaormpro-2.0/) + [SeaORM 2.0: Nested ActiveModel](https://www.sea-ql.org/blog/2025-11-25-sea-orm-2.0/) + [A walk-through of SeaORM 2.0](https://www.sea-ql.org/blog/2025-12-05-sea-orm-2.0/) + [How we made SeaORM synchronous](https://www.sea-ql.org/blog/2025-12-12-sea-orm-2.0/) + [SeaORM 2.0 Migration Guide](https://www.sea-ql.org/blog/2026-01-12-sea-orm-2.0/) + [SeaORM now supports Arrow & Parquet](https://www.sea-ql.org/blog/2026-02-22-sea-orm-arrow/) + [SeaORM 2.0 with SQL Server Support](https://www.sea-ql.org/blog/2026-02-25-sea-orm-x/) 如果你广泛使用 SeaQuery,我们建议你查看我们关于 SeaQuery 1.0 发布的博客文章: + [The road to SeaQuery 1.0](https://www.sea-ql.org/blog/2025-08-30-sea-query-1.0/) ## 许可证 根据以下任一许可证授权 - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) 或 ) - MIT license ([LICENSE-MIT](LICENSE-MIT) 或 ) 根据你的选择。 ## 贡献 除非你明确声明,否则根据 Apache-2.0 许可证定义,你有意提交以包含在作品中的任何贡献, 应按上述方式双重许可,不附加任何额外条款或条件。 我们邀请你参与、贡献,共同帮助构建 Rust 的未来。 向我们的贡献者致以崇高的敬意! [![Contributors](https://opencollective.com/sea-orm/contributors.svg?width=1000&button=false)](https://github.com/SeaQL/sea-orm/graphs/contributors) ## 谁在使用 SeaORM? 以下是用 SeaORM 构建的一些很棒的开源软件的简短列表。欢迎[提交你的项目](https://github.com/SeaQL/sea-orm/blob/master/COMMUNITY.md#built-with-seaorm)! | 项目 | GitHub | 标语 | |---------|--------|---------| | [Zed](https://github.com/zed-industries/zed) | ![GitHub stars](https://img.shields.io/github/stars/zed-industries/zed.svg?style=social) | 高性能、多人协作的代码编辑器 | | [OpenObserve](https://github.com/openobserve/openobserve) | ![GitHub stars](https://img.shields.io/github/stars/openobserve/openobserve.svg?style=social) | 开源可观测性平台 | | [RisingWave](https://github.com/risingwavelabs/risingwave) | ![GitHub stars](https://img.shields.io/github/stars/risingwavelabs/risingwave.svg?style=social) | 流处理和管理平台 | | [LLDAP](https://github.com/nitnelave/lldap) | ![GitHub stars](https://img.shields.io/github/stars/nitnelave/lldap.svg?style=social) | 用于用户管理的轻量级 LDAP 服务器 | | [Warpgate](https://github.com/warp-tech/warpgate) | ![GitHub stars](https://img.shields.io/github/stars/warp-tech/warpgate.svg?style=social) | 支持任何 SSH 客户端的智能 SSH 堡垒机 | | [Svix](https://github.com/svix/svix-webhooks) | ![GitHub stars](https://img.shields.io/github/stars/svix/svix-webhooks.svg?style=social) | 企业级 webhooks 服务 | | [Ryot](https://github.com/IgnisDa/ryot) | ![GitHub stars](https://img.shields.io/github/stars/ignisda/ryot.svg?style=social) | 你唯一需要的自托管追踪器 | | [Lapdev](https://github.com/lapce/lapdev) | ![GitHub stars](https://img.shields.io/github/stars/lapce/lapdev.svg?style=social) | 自托管远程开发环境 | | [System Initiative](https://github.com/systeminit/si) | ![GitHub stars](https://img.shields.io/github/stars/systeminit/si.svg?style=social) | DevOps 自动化平台 | | [OctoBase](https://github.com/toeverything/OctoBase) | ![GitHub stars](https://img.shields.io/github/stars/toeverything/OctoBase.svg?style=social) | 轻量级、可扩展、离线的协作数据后端 | ## 赞助 [SeaQL.org](https://www.sea-ql.org/) 是一个由充满激情的开发者运营的独立开源组织。 如果你感到慷慨,通过 [GitHub Sponsor](https://github.com/sponsors/SeaQL) 提供的小额捐赠将不胜感激,这对维持该组织的运营大有帮助。 ### 金牌赞助商
[QDX](https://qdx.co/) 开创了基于量子动力学的药物发现,利用 AI 和超级计算加速分子建模。 我们非常感谢 QDX 赞助 SeaORM 的开发,SeaORM 是支持其数据密集型应用的 SQL 工具包。 ### 银牌赞助商 我们要感谢我们的银牌赞助商:Digital Ocean,感谢他们赞助我们的服务器。以及 JetBrains,感谢他们赞助我们的 IDE。
## 吉祥物 Terres 是一只寄居,它是 Ferris 的朋友,也是 SeaORM 的官方吉祥物。他的爱好是收集贝壳。 Terres ## 🦀 Rustacean 贴纸包 Rustacean 贴纸包是表达你对 Rust 热情的完美方式。我们的贴纸由优质防水乙烯基制成,具有独特的哑光饰面。 贴纸包内容: + SeaQL 项目 Logo:SeaQL, SeaORM, SeaQuery, Seaography + 吉祥物:Ferris the Crab x 3, Terres the Hermit Crab + The Rustacean wordmark [支持 SeaQL 并获取贴纸包!](https://www.sea-ql.org/sticker-pack/) 所有收益将直接用于 SeaQL 项目的持续开发。 Rustacean Sticker Pack by SeaQL
标签:Actix, Axum, CRUD, GraphQL, gRPC, ORM, RESTful, Rust, Rust生态, SeaORM, SeaQL, SQL, Syscall, Web开发, 中间件, 关系型数据库, 分页, 可视化界面, 后端, 多线程, 对象关系映射, 开发框架, 开源库, 异步, 搜索引擎爬虫, 数据库, 数据库迁移, 数据访问层, 模型关联, 测试用例, 系统审计, 网络流量审计, 过滤器, 通知系统