sea_orm/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![warn(missing_docs)]
3#![deny(
4    missing_debug_implementations,
5    clippy::missing_panics_doc,
6    clippy::unwrap_used,
7    clippy::print_stderr,
8    clippy::print_stdout
9)]
10
11//! <div align="center">
12//!
13//!   <img src="https://www.sea-ql.org/SeaORM/img/SeaORM banner.png"/>
14//!
15//!   <h1>SeaORM</h1>
16//!
17//!   <h3>🐚 An async & dynamic ORM for Rust</h3>
18//!
19//!   [![crate](https://img.shields.io/crates/v/sea-orm.svg)](https://crates.io/crates/sea-orm)
20//!   [![docs](https://docs.rs/sea-orm/badge.svg)](https://docs.rs/sea-orm)
21//!   [![build status](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml/badge.svg)](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml)
22//!
23//! </div>
24//!
25//! # SeaORM
26//!
27//! #### SeaORM is a relational ORM to help you build web services in Rust with the familiarity of dynamic languages.
28//!
29//! [![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/)
30//! If you like what we do, consider starring, sharing and contributing!
31//!
32//! Please help us with maintaining SeaORM by completing the [SeaQL Community Survey 2024](https://sea-ql.org/community-survey)!
33//!
34//! [![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv)
35//! Join our Discord server to chat with other members of the SeaQL community!
36//!
37//! ## Getting Started
38//!
39//! + [Documentation](https://www.sea-ql.org/SeaORM)
40//! + [Tutorial](https://www.sea-ql.org/sea-orm-tutorial)
41//! + [Cookbook](https://www.sea-ql.org/sea-orm-cookbook)
42//!
43//! Integration examples:
44//!
45//! + [Actix v4 Example](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example)
46//! + [Axum Example](https://github.com/SeaQL/sea-orm/tree/master/examples/axum_example)
47//! + [GraphQL Example](https://github.com/SeaQL/sea-orm/tree/master/examples/graphql_example)
48//! + [jsonrpsee Example](https://github.com/SeaQL/sea-orm/tree/master/examples/jsonrpsee_example)
49//! + [Loco TODO 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)
50//! + [Poem Example](https://github.com/SeaQL/sea-orm/tree/master/examples/poem_example)
51//! + [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)
52//! + [Salvo Example](https://github.com/SeaQL/sea-orm/tree/master/examples/salvo_example)
53//! + [Tonic Example](https://github.com/SeaQL/sea-orm/tree/master/examples/tonic_example)
54//! + [Seaography Example](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example)
55//!
56//! ## Features
57//!
58//! 1. Async
59//!
60//!     Relying on [SQLx](https://github.com/launchbadge/sqlx), SeaORM is a new library with async support from day 1.
61//!
62//! 2. Dynamic
63//!
64//!     Built upon [SeaQuery](https://github.com/SeaQL/sea-query), SeaORM allows you to build complex dynamic queries.
65//!
66//! 3. Service Oriented
67//!
68//!     Quickly build services that join, filter, sort and paginate data in REST, GraphQL and gRPC APIs.
69//!
70//! 4. Production Ready
71//!
72//!     SeaORM is feature-rich, well-tested and used in production by companies and startups.
73//!
74//! ## A quick taste of SeaORM
75//!
76//! ### Entity
77//! ```
78//! # #[cfg(feature = "macros")]
79//! # mod entities {
80//! # mod fruit {
81//! # use sea_orm::entity::prelude::*;
82//! # #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
83//! # #[sea_orm(table_name = "fruit")]
84//! # pub struct Model {
85//! #     #[sea_orm(primary_key)]
86//! #     pub id: i32,
87//! #     pub name: String,
88//! #     pub cake_id: Option<i32>,
89//! # }
90//! # #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
91//! # pub enum Relation {
92//! #     #[sea_orm(
93//! #         belongs_to = "super::cake::Entity",
94//! #         from = "Column::CakeId",
95//! #         to = "super::cake::Column::Id"
96//! #     )]
97//! #     Cake,
98//! # }
99//! # impl Related<super::cake::Entity> for Entity {
100//! #     fn to() -> RelationDef {
101//! #         Relation::Cake.def()
102//! #     }
103//! # }
104//! # impl ActiveModelBehavior for ActiveModel {}
105//! # }
106//! # mod cake {
107//! use sea_orm::entity::prelude::*;
108//!
109//! #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
110//! #[sea_orm(table_name = "cake")]
111//! pub struct Model {
112//!     #[sea_orm(primary_key)]
113//!     pub id: i32,
114//!     pub name: String,
115//! }
116//!
117//! #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
118//! pub enum Relation {
119//!     #[sea_orm(has_many = "super::fruit::Entity")]
120//!     Fruit,
121//! }
122//!
123//! impl Related<super::fruit::Entity> for Entity {
124//!     fn to() -> RelationDef {
125//!         Relation::Fruit.def()
126//!     }
127//! }
128//! # impl ActiveModelBehavior for ActiveModel {}
129//! # }
130//! # }
131//! ```
132//!
133//! ### Select
134//! ```
135//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
136//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
137//! // find all models
138//! let cakes: Vec<cake::Model> = Cake::find().all(db).await?;
139//!
140//! // find and filter
141//! let chocolate: Vec<cake::Model> = Cake::find()
142//!     .filter(cake::Column::Name.contains("chocolate"))
143//!     .all(db)
144//!     .await?;
145//!
146//! // find one model
147//! let cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;
148//! let cheese: cake::Model = cheese.unwrap();
149//!
150//! // find related models (lazy)
151//! let fruits: Vec<fruit::Model> = cheese.find_related(Fruit).all(db).await?;
152//!
153//! // find related models (eager)
154//! let cake_with_fruits: Vec<(cake::Model, Vec<fruit::Model>)> =
155//!     Cake::find().find_with_related(Fruit).all(db).await?;
156//!
157//! # Ok(())
158//! # }
159//! ```
160//!
161//! ### Nested Select
162//!
163//! ```
164//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
165//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
166//! use sea_orm::DerivePartialModel;
167//!
168//! #[derive(DerivePartialModel)]
169//! #[sea_orm(entity = "cake::Entity", from_query_result)]
170//! struct CakeWithFruit {
171//!     id: i32,
172//!     name: String,
173//!     #[sea_orm(nested)]
174//!     fruit: Option<Fruit>,
175//! }
176//!
177//! #[derive(DerivePartialModel)]
178//! #[sea_orm(entity = "fruit::Entity", from_query_result)]
179//! struct Fruit {
180//!     id: i32,
181//!     name: String,
182//! }
183//!
184//! let cakes: Vec<CakeWithFruit> = cake::Entity::find()
185//!     .left_join(fruit::Entity)
186//!     .into_partial_model()
187//!     .all(db)
188//!     .await?;
189//! # Ok(())
190//! # }
191//! ```
192//! ### Insert
193//! ```
194//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
195//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
196//! let apple = fruit::ActiveModel {
197//!     name: Set("Apple".to_owned()),
198//!     ..Default::default() // no need to set primary key
199//! };
200//!
201//! let pear = fruit::ActiveModel {
202//!     name: Set("Pear".to_owned()),
203//!     ..Default::default()
204//! };
205//!
206//! // insert one
207//! let pear = pear.insert(db).await?;
208//! # Ok(())
209//! # }
210//! # async fn function2(db: &DbConn) -> Result<(), DbErr> {
211//! # let apple = fruit::ActiveModel {
212//! #     name: Set("Apple".to_owned()),
213//! #     ..Default::default() // no need to set primary key
214//! # };
215//! # let pear = fruit::ActiveModel {
216//! #     name: Set("Pear".to_owned()),
217//! #     ..Default::default()
218//! # };
219//!
220//! // insert many
221//! Fruit::insert_many([apple, pear]).exec(db).await?;
222//! # Ok(())
223//! # }
224//! ```
225//! ### Update
226//! ```
227//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
228//! use sea_orm::sea_query::{Expr, Value};
229//!
230//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
231//! let pear: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;
232//! let mut pear: fruit::ActiveModel = pear.unwrap().into();
233//!
234//! pear.name = Set("Sweet pear".to_owned());
235//!
236//! // update one
237//! let pear: fruit::Model = pear.update(db).await?;
238//!
239//! // update many: UPDATE "fruit" SET "cake_id" = NULL WHERE "fruit"."name" LIKE '%Apple%'
240//! Fruit::update_many()
241//!     .col_expr(fruit::Column::CakeId, Expr::value(Value::Int(None)))
242//!     .filter(fruit::Column::Name.contains("Apple"))
243//!     .exec(db)
244//!     .await?;
245//!
246//! # Ok(())
247//! # }
248//! ```
249//! ### Save
250//! ```
251//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
252//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
253//! let banana = fruit::ActiveModel {
254//!     id: NotSet,
255//!     name: Set("Banana".to_owned()),
256//!     ..Default::default()
257//! };
258//!
259//! // create, because primary key `id` is `NotSet`
260//! let mut banana = banana.save(db).await?;
261//!
262//! banana.name = Set("Banana Mongo".to_owned());
263//!
264//! // update, because primary key `id` is `Set`
265//! let banana = banana.save(db).await?;
266//!
267//! # Ok(())
268//! # }
269//! ```
270//! ### Delete
271//! ```
272//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
273//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
274//! // delete one
275//! let orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;
276//! let orange: fruit::Model = orange.unwrap();
277//! fruit::Entity::delete(orange.into_active_model())
278//!     .exec(db)
279//!     .await?;
280//!
281//! // or simply
282//! let orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;
283//! let orange: fruit::Model = orange.unwrap();
284//! orange.delete(db).await?;
285//!
286//! // delete many: DELETE FROM "fruit" WHERE "fruit"."name" LIKE 'Orange'
287//! fruit::Entity::delete_many()
288//!     .filter(fruit::Column::Name.contains("Orange"))
289//!     .exec(db)
290//!     .await?;
291//!
292//! # Ok(())
293//! # }
294//! ```
295//!
296//! ## 🧭 Seaography: instant GraphQL API
297//!
298//! [Seaography](https://github.com/SeaQL/seaography) is a GraphQL framework built on top of SeaORM. Seaography allows you to build GraphQL resolvers quickly. With just a few commands, you can launch a GraphQL server from SeaORM entities!
299//!
300//! Look at the [Seaography Example](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) to learn more.
301//!
302//! <img src="https://raw.githubusercontent.com/SeaQL/sea-orm/master/examples/seaography_example/Seaography%20example.png"/>
303//!
304//! ## πŸ–₯️ SeaORM Pro: Effortless Admin Panel
305//!
306//! [SeaORM Pro](https://www.sea-ql.org/sea-orm-pro/) is an admin panel solution allowing you to quickly and easily launch an admin panel for your application - frontend development skills not required, but certainly nice to have!
307//!
308//! Features:
309//!
310//! + Full CRUD
311//! + Built on React + GraphQL
312//! + Built-in GraphQL resolver
313//! + Customize the UI with simple TOML
314//!
315//! Learn More
316//!
317//! + [Example Repo](https://github.com/SeaQL/sea-orm-pro)
318//! + [Getting Started with Loco](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started-loco/)
319//! + [Getting Started with Axum](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started-axum/)
320//!
321//! ![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-dark.png#gh-dark-mode-only)
322//! ![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-light.png#gh-light-mode-only)
323//!
324//! ## Releases
325//!
326//! [SeaORM 1.0](https://www.sea-ql.org/blog/2024-08-04-sea-orm-1.0/) is a stable release. The 1.x version will be updated until at least October 2025, and we'll decide whether to release a 2.0 version or extend the 1.x life cycle.
327//!
328//! It doesn't mean that SeaORM is 'done', we've designed an architecture to allow us to deliver new features without major breaking changes. In fact, more features are coming!
329//!
330//! + [Change Log](https://github.com/SeaQL/sea-orm/tree/master/CHANGELOG.md)
331//!
332//! ### Who's using SeaORM?
333//!
334//! Here is a short list of awesome open source software built with SeaORM. [Full list here](https://github.com/SeaQL/sea-orm/blob/master/COMMUNITY.md#built-with-seaorm). Feel free to submit yours!
335//!
336//! | Project | GitHub | Tagline |
337//! |---------|--------|---------|
338//! | [Zed](https://github.com/zed-industries/zed) | ![GitHub stars](https://img.shields.io/github/stars/zed-industries/zed.svg?style=social) | A high-performance, multiplayer code editor |
339//! | [OpenObserve](https://github.com/openobserve/openobserve) | ![GitHub stars](https://img.shields.io/github/stars/openobserve/openobserve.svg?style=social) | Open-source observability platform |
340//! | [RisingWave](https://github.com/risingwavelabs/risingwave) | ![GitHub stars](https://img.shields.io/github/stars/risingwavelabs/risingwave.svg?style=social) | Stream processing and management platform |
341//! | [LLDAP](https://github.com/nitnelave/lldap) | ![GitHub stars](https://img.shields.io/github/stars/nitnelave/lldap.svg?style=social) | A light LDAP server for user management |
342//! | [Warpgate](https://github.com/warp-tech/warpgate) | ![GitHub stars](https://img.shields.io/github/stars/warp-tech/warpgate.svg?style=social) | Smart SSH bastion that works with any SSH client |
343//! | [Svix](https://github.com/svix/svix-webhooks) | ![GitHub stars](https://img.shields.io/github/stars/svix/svix-webhooks.svg?style=social) | The enterprise ready webhooks service |
344//! | [Ryot](https://github.com/IgnisDa/ryot) | ![GitHub stars](https://img.shields.io/github/stars/ignisda/ryot.svg?style=social) | The only self hosted tracker you will ever need |
345//! | [Lapdev](https://github.com/lapce/lapdev) | ![GitHub stars](https://img.shields.io/github/stars/lapce/lapdev.svg?style=social) | Self-hosted remote development enviroment |
346//! | [System Initiative](https://github.com/systeminit/si) | ![GitHub stars](https://img.shields.io/github/stars/systeminit/si.svg?style=social) | DevOps Automation Platform |
347//! | [OctoBase](https://github.com/toeverything/OctoBase) | ![GitHub stars](https://img.shields.io/github/stars/toeverything/OctoBase.svg?style=social) | A light-weight, scalable, offline collaborative data backend |
348//!
349//! ## License
350//!
351//! Licensed under either of
352//!
353//! -   Apache License, Version 2.0
354//!     ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
355//! -   MIT license
356//!     ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
357//!
358//! at your option.
359//!
360//! ## Contribution
361//!
362//! Unless you explicitly state otherwise, any contribution intentionally submitted
363//! for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
364//! dual licensed as above, without any additional terms or conditions.
365//!
366//! We invite you to participate, contribute and together help build Rust's future.
367//!
368//! A big shout out to our contributors!
369//!
370//! [![Contributors](https://opencollective.com/sea-orm/contributors.svg?width=1000&button=false)](https://github.com/SeaQL/sea-orm/graphs/contributors)
371//!
372//! ## Sponsorship
373//!
374//! [SeaQL.org](https://www.sea-ql.org/) is an independent open-source organization run by passionate developers. If you enjoy using our libraries, please star and share our repositories. If you feel generous, a small donation via [GitHub Sponsor](https://github.com/sponsors/SeaQL) will be greatly appreciated, and goes a long way towards sustaining the organization.
375//!
376//! ### Gold Sponsors
377//!
378//! <table><tr>
379//! <td><a href="https://qdx.co/">
380//!   <img src="https://www.sea-ql.org/static/sponsors/QDX.svg" width="138"/>
381//! </a></td>
382//! </tr></table>
383//!
384//! [QDX](https://qdx.co/) pioneers quantum dynamics-powered drug discovery, leveraging AI and supercomputing to accelerate molecular modeling.
385//! We're immensely grateful to QDX for sponsoring the development of SeaORM, the SQL toolkit that powers their data engineering workflows.
386//!
387//! ### Silver Sponsors
388//!
389//! We’re grateful to our silver sponsors: Digital Ocean, for sponsoring our servers. And JetBrains, for sponsoring our IDE.
390//!
391//! <table><tr>
392//! <td><a href="https://www.digitalocean.com/">
393//!   <img src="https://www.sea-ql.org/static/sponsors/DigitalOcean.svg" width="125">
394//! </a></td>
395//!
396//! <td><a href="https://www.jetbrains.com/">
397//!   <img src="https://www.sea-ql.org/static/sponsors/JetBrains.svg" width="125">
398//! </a></td>
399//! </tr></table>
400//!
401//! ## Mascot
402//!
403//! A friend of Ferris, Terres the hermit crab is the official mascot of SeaORM. His hobby is collecting shells.
404//!
405//! <img alt="Terres" src="https://www.sea-ql.org/SeaORM/img/Terres.png" width="400"/>
406//!
407//! ### Rustacean Sticker Pack πŸ¦€
408//!
409//! The Rustacean Sticker Pack is the perfect way to express your passion for Rust.
410//! Our stickers are made with a premium water-resistant vinyl with a unique matte finish.
411//! Stick them on your laptop, notebook, or any gadget to show off your love for Rust!
412//!
413//! Sticker Pack Contents:
414//! - Logo of SeaQL projects: SeaQL, SeaORM, SeaQuery, Seaography, FireDBG
415//! - Mascot of SeaQL: Terres the Hermit Crab
416//! - Mascot of Rust: Ferris the Crab
417//! - The Rustacean word
418//!
419//! [Support SeaQL and get a Sticker Pack!](https://www.sea-ql.org/sticker-pack/) All proceeds contributes directly to the ongoing development of SeaQL projects.
420//!
421//! <a href="https://www.sea-ql.org/sticker-pack/"><img alt="Rustacean Sticker Pack by SeaQL" src="https://www.sea-ql.org/static/sticker-pack-1s.jpg" width="600"/></a>
422#![doc(
423    html_logo_url = "https://raw.githubusercontent.com/SeaQL/sea-query/master/docs/SeaQL icon dark.png"
424)]
425
426mod database;
427mod docs;
428mod driver;
429/// Module for the Entity type and operations
430pub mod entity;
431/// Error types for all database operations
432pub mod error;
433/// This module performs execution of queries on a Model or ActiveModel
434mod executor;
435/// Types and methods to perform metric collection
436pub mod metric;
437/// Types and methods to perform queries
438pub mod query;
439/// Types that defines the schemas of an Entity
440pub mod schema;
441/// Helpers for working with Value
442pub mod value;
443
444#[doc(hidden)]
445#[cfg(all(feature = "macros", feature = "tests-cfg"))]
446pub mod tests_cfg;
447mod util;
448
449pub use database::*;
450#[allow(unused_imports)]
451pub use driver::*;
452pub use entity::*;
453pub use error::*;
454pub use executor::*;
455pub use query::*;
456pub use schema::*;
457
458#[cfg(feature = "macros")]
459pub use sea_orm_macros::{
460    DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn,
461    DeriveCustomColumn, DeriveDisplay, DeriveEntity, DeriveEntityModel, DeriveIden,
462    DeriveIntoActiveModel, DeriveMigrationName, DeriveModel, DerivePartialModel, DerivePrimaryKey,
463    DeriveRelatedEntity, DeriveRelation, DeriveValueType, FromJsonQueryResult, FromQueryResult,
464};
465
466pub use sea_query;
467pub use sea_query::Iden;
468
469pub use sea_orm_macros::EnumIter;
470pub use strum;
471
472#[cfg(feature = "sqlx-dep")]
473pub use sqlx;