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. Testable
67//!
68//!     Use mock connections and/or SQLite to write tests for your application logic.
69//!
70//! 4. Service Oriented
71//!
72//!     Quickly build services that join, filter, sort and paginate data in REST, GraphQL and gRPC APIs.
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//! ### Insert
161//! ```
162//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
163//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
164//! let apple = fruit::ActiveModel {
165//!     name: Set("Apple".to_owned()),
166//!     ..Default::default() // no need to set primary key
167//! };
168//!
169//! let pear = fruit::ActiveModel {
170//!     name: Set("Pear".to_owned()),
171//!     ..Default::default()
172//! };
173//!
174//! // insert one
175//! let pear = pear.insert(db).await?;
176//! # Ok(())
177//! # }
178//! # async fn function2(db: &DbConn) -> Result<(), DbErr> {
179//! # let apple = fruit::ActiveModel {
180//! #     name: Set("Apple".to_owned()),
181//! #     ..Default::default() // no need to set primary key
182//! # };
183//! # let pear = fruit::ActiveModel {
184//! #     name: Set("Pear".to_owned()),
185//! #     ..Default::default()
186//! # };
187//!
188//! // insert many
189//! Fruit::insert_many([apple, pear]).exec(db).await?;
190//! # Ok(())
191//! # }
192//! ```
193//! ### Update
194//! ```
195//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
196//! use sea_orm::sea_query::{Expr, Value};
197//!
198//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
199//! let pear: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;
200//! let mut pear: fruit::ActiveModel = pear.unwrap().into();
201//!
202//! pear.name = Set("Sweet pear".to_owned());
203//!
204//! // update one
205//! let pear: fruit::Model = pear.update(db).await?;
206//!
207//! // update many: UPDATE "fruit" SET "cake_id" = NULL WHERE "fruit"."name" LIKE '%Apple%'
208//! Fruit::update_many()
209//!     .col_expr(fruit::Column::CakeId, Expr::value(Value::Int(None)))
210//!     .filter(fruit::Column::Name.contains("Apple"))
211//!     .exec(db)
212//!     .await?;
213//!
214//! # Ok(())
215//! # }
216//! ```
217//! ### Save
218//! ```
219//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
220//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
221//! let banana = fruit::ActiveModel {
222//!     id: NotSet,
223//!     name: Set("Banana".to_owned()),
224//!     ..Default::default()
225//! };
226//!
227//! // create, because primary key `id` is `NotSet`
228//! let mut banana = banana.save(db).await?;
229//!
230//! banana.name = Set("Banana Mongo".to_owned());
231//!
232//! // update, because primary key `id` is `Set`
233//! let banana = banana.save(db).await?;
234//!
235//! # Ok(())
236//! # }
237//! ```
238//! ### Delete
239//! ```
240//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
241//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
242//! // delete one
243//! let orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;
244//! let orange: fruit::Model = orange.unwrap();
245//! fruit::Entity::delete(orange.into_active_model())
246//!     .exec(db)
247//!     .await?;
248//!
249//! // or simply
250//! let orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;
251//! let orange: fruit::Model = orange.unwrap();
252//! orange.delete(db).await?;
253//!
254//! // delete many: DELETE FROM "fruit" WHERE "fruit"."name" LIKE 'Orange'
255//! fruit::Entity::delete_many()
256//!     .filter(fruit::Column::Name.contains("Orange"))
257//!     .exec(db)
258//!     .await?;
259//!
260//! # Ok(())
261//! # }
262//! ```
263//!
264//! ## 🧭 Seaography: instant GraphQL API
265//!
266//! [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!
267//!
268//! Look at the [Seaography Example](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) to learn more.
269//!
270//! <img src="https://raw.githubusercontent.com/SeaQL/sea-orm/master/examples/seaography_example/Seaography%20example.png"/>
271//!
272//! ## πŸ–₯️ SeaORM Pro: Effortless Admin Panel
273//!
274//! [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!
275//!
276//! Features:
277//!
278//! + Full CRUD
279//! + Built on React + GraphQL
280//! + Built-in GraphQL resolver
281//! + Customize the UI with simple TOML
282//!
283//! Learn More
284//!
285//! + [Example Repo](https://github.com/SeaQL/sea-orm-pro)
286//! + [Getting Started with Loco](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started-loco/)
287//! + [Getting Started with Axum](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started-axum/)
288//!
289//! ![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-dark.png#gh-dark-mode-only)
290//! ![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-light.png#gh-light-mode-only)
291//!
292//! ## Releases
293//!
294//! [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.
295//!
296//! 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!
297//!
298//! + [Change Log](https://github.com/SeaQL/sea-orm/tree/master/CHANGELOG.md)
299//!
300//! ### Who's using SeaORM?
301//!
302//! See [Built with SeaORM](https://github.com/SeaQL/sea-orm/blob/master/COMMUNITY.md#built-with-seaorm). Feel free to [submit yours](https://github.com/SeaQL/sea-orm/issues/403)!
303//!
304//! ## License
305//!
306//! Licensed under either of
307//!
308//! -   Apache License, Version 2.0
309//!     ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
310//! -   MIT license
311//!     ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
312//!
313//! at your option.
314//!
315//! ## Contribution
316//!
317//! Unless you explicitly state otherwise, any contribution intentionally submitted
318//! for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
319//! dual licensed as above, without any additional terms or conditions.
320//!
321//! We invite you to participate, contribute and together help build Rust's future.
322//!
323//! A big shout out to our contributors!
324//!
325//! [![Contributors](https://opencollective.com/sea-orm/contributors.svg?width=1000&button=false)](https://github.com/SeaQL/sea-orm/graphs/contributors)
326//!
327//! ## Sponsorship
328//!
329//! [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.
330//!
331//! ### Silver Sponsors
332//!
333//! <table><tr>
334//! <td><a href="https://www.digitalocean.com/">
335//!   <img src="https://www.sea-ql.org/static/sponsors/DigitalOcean.svg" width="125">
336//! </a></td>
337//!
338//! <td><a href="https://www.jetbrains.com/">
339//!   <img src="https://www.sea-ql.org/static/sponsors/JetBrains.svg" width="125">
340//! </a></td>
341//! </tr></table>
342//!
343//! We’re immensely grateful to our sponsors: Digital Ocean, for sponsoring our servers. And JetBrains, for sponsoring our IDE.
344//!
345//! ## Mascot
346//!
347//! A friend of Ferris, Terres the hermit crab is the official mascot of SeaORM. His hobby is collecting shells.
348//!
349//! <img alt="Terres" src="https://www.sea-ql.org/SeaORM/img/Terres.png" width="400"/>
350#![doc(
351    html_logo_url = "https://raw.githubusercontent.com/SeaQL/sea-query/master/docs/SeaQL icon dark.png"
352)]
353
354mod database;
355mod docs;
356mod driver;
357/// Module for the Entity type and operations
358pub mod entity;
359/// Error types for all database operations
360pub mod error;
361/// This module performs execution of queries on a Model or ActiveModel
362mod executor;
363/// Holds types and methods to perform metric collection
364pub mod metric;
365/// Holds types and methods to perform queries
366pub mod query;
367/// Holds types that defines the schemas of an Entity
368pub mod schema;
369#[doc(hidden)]
370#[cfg(all(feature = "macros", feature = "tests-cfg"))]
371pub mod tests_cfg;
372mod util;
373
374pub use database::*;
375#[allow(unused_imports)]
376pub use driver::*;
377pub use entity::*;
378pub use error::*;
379pub use executor::*;
380pub use query::*;
381pub use schema::*;
382
383#[cfg(feature = "macros")]
384pub use sea_orm_macros::{
385    DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn,
386    DeriveCustomColumn, DeriveDisplay, DeriveEntity, DeriveEntityModel, DeriveIden,
387    DeriveIntoActiveModel, DeriveMigrationName, DeriveModel, DerivePartialModel, DerivePrimaryKey,
388    DeriveRelatedEntity, DeriveRelation, DeriveValueType, FromJsonQueryResult, FromQueryResult,
389};
390
391pub use sea_query;
392pub use sea_query::Iden;
393
394pub use sea_orm_macros::EnumIter;
395pub use strum;
396
397#[cfg(feature = "sqlx-dep")]
398pub use sqlx;