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//! [](https://crates.io/crates/sea-orm)
20//! [](https://docs.rs/sea-orm)
21//! [](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml)
22//!
23//! </div>
24//!
25//! # SeaORM
26//!
27//! [中文文档](https://github.com/SeaQL/sea-orm/blob/master/README-zh.md)
28//!
29//! #### SeaORM is a relational ORM to help you build web services in Rust with the familiarity of dynamic languages.
30//!
31//! [](https://github.com/SeaQL/sea-orm/stargazers/)
32//! If you like what we do, consider starring, sharing and contributing!
33//!
34//! Please help us with maintaining SeaORM by completing the [SeaQL Community Survey 2025](https://www.sea-ql.org/community-survey/)!
35//!
36//! [](https://discord.com/invite/uCPdDXzbdv)
37//! Join our Discord server to chat with other members of the SeaQL community!
38//!
39//! ## Getting Started
40//!
41//! + [Documentation](https://www.sea-ql.org/SeaORM)
42//! + [Tutorial](https://www.sea-ql.org/sea-orm-tutorial)
43//! + [Cookbook](https://www.sea-ql.org/sea-orm-cookbook)
44//!
45//! Integration examples:
46//!
47//! + [Actix v4 Example](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example)
48//! + [Axum Example](https://github.com/SeaQL/sea-orm/tree/master/examples/axum_example)
49//! + [GraphQL Example](https://github.com/SeaQL/sea-orm/tree/master/examples/graphql_example)
50//! + [jsonrpsee Example](https://github.com/SeaQL/sea-orm/tree/master/examples/jsonrpsee_example)
51//! + [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)
52//! + [Poem Example](https://github.com/SeaQL/sea-orm/tree/master/examples/poem_example)
53//! + [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)
54//! + [Salvo Example](https://github.com/SeaQL/sea-orm/tree/master/examples/salvo_example)
55//! + [Tonic Example](https://github.com/SeaQL/sea-orm/tree/master/examples/tonic_example)
56//! + [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)
57//!
58//! If you want a simple, clean example that fits in a single file that demonstrates the best of SeaORM, you can try:
59//! + [Quickstart](https://github.com/SeaQL/sea-orm/blob/master/examples/quickstart/src/main.rs)
60//!
61//! ## Features
62//!
63//! 1. Async
64//!
65//! Relying on [SQLx](https://github.com/launchbadge/sqlx), SeaORM is a new library with async support from day 1.
66//!
67//! 2. Dynamic
68//!
69//! Built upon [SeaQuery](https://github.com/SeaQL/sea-query), SeaORM allows you to build complex dynamic queries.
70//!
71//! 3. Service Oriented
72//!
73//! Quickly build services that join, filter, sort and paginate data in REST, GraphQL and gRPC APIs.
74//!
75//! 4. Production Ready
76//!
77//! SeaORM is feature-rich, well-tested and used in production by companies and startups.
78//!
79//! Let's have a quick walk through of the unique features of SeaORM.
80//!
81//! ## Expressive Entity format
82//! You don't have to write this by hand! Entity files can be generated from an existing database using `sea-orm-cli`,
83//! following is generated with `--entity-format dense` *(new in 2.0)*.
84//! ```
85//! # #[cfg(feature = "macros")]
86//! # mod entities {
87//! # mod profile {
88//! # use sea_orm::entity::prelude::*;
89//! # #[sea_orm::model]
90//! # #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
91//! # #[sea_orm(table_name = "profile")]
92//! # pub struct Model {
93//! # #[sea_orm(primary_key)]
94//! # pub id: i32,
95//! # pub picture: String,
96//! # #[sea_orm(unique)]
97//! # pub user_id: i32,
98//! # #[sea_orm(belongs_to, from = "user_id", to = "id")]
99//! # pub user: HasOne<super::user::Entity>,
100//! # }
101//! # impl ActiveModelBehavior for ActiveModel {}
102//! # }
103//! # mod tag {
104//! # use sea_orm::entity::prelude::*;
105//! # #[sea_orm::model]
106//! # #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
107//! # #[sea_orm(table_name = "post")]
108//! # pub struct Model {
109//! # #[sea_orm(primary_key)]
110//! # pub id: i32,
111//! # #[sea_orm(has_many, via = "post_tag")]
112//! # pub tags: HasMany<super::tag::Entity>,
113//! # }
114//! # impl ActiveModelBehavior for ActiveModel {}
115//! # }
116//! # mod post_tag {
117//! # use sea_orm::entity::prelude::*;
118//! # #[sea_orm::model]
119//! # #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
120//! # #[sea_orm(table_name = "post_tag")]
121//! # pub struct Model {
122//! # #[sea_orm(primary_key, auto_increment = false)]
123//! # pub post_id: i32,
124//! # #[sea_orm(primary_key, auto_increment = false)]
125//! # pub tag_id: i32,
126//! # #[sea_orm(belongs_to, from = "post_id", to = "id")]
127//! # pub post: Option<super::post::Entity>,
128//! # #[sea_orm(belongs_to, from = "tag_id", to = "id")]
129//! # pub tag: Option<super::tag::Entity>,
130//! # }
131//! # impl ActiveModelBehavior for ActiveModel {}
132//! # }
133//! mod user {
134//! use sea_orm::entity::prelude::*;
135//!
136//! #[sea_orm::model]
137//! #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
138//! #[sea_orm(table_name = "user")]
139//! pub struct Model {
140//! #[sea_orm(primary_key)]
141//! pub id: i32,
142//! pub name: String,
143//! #[sea_orm(unique)]
144//! pub email: String,
145//! #[sea_orm(has_one)]
146//! pub profile: HasOne<super::profile::Entity>,
147//! #[sea_orm(has_many)]
148//! pub posts: HasMany<super::post::Entity>,
149//! }
150//! # impl ActiveModelBehavior for ActiveModel {}
151//! }
152//! mod post {
153//! use sea_orm::entity::prelude::*;
154//!
155//! #[sea_orm::model]
156//! #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
157//! #[sea_orm(table_name = "post")]
158//! pub struct Model {
159//! #[sea_orm(primary_key)]
160//! pub id: i32,
161//! pub user_id: i32,
162//! pub body: String,
163//! #[sea_orm(belongs_to, from = "user_id", to = "id")]
164//! pub author: HasOne<super::user::Entity>,
165//! #[sea_orm(has_many, via = "post_tag")] // M-N relation with junction
166//! pub tags: HasMany<super::tag::Entity>,
167//! }
168//! # impl ActiveModelBehavior for ActiveModel {}
169//! }
170//! # }
171//! ```
172//!
173//! ## Smart Entity Loader
174//! The Entity Loader intelligently uses join for 1-1 and data loader for 1-N relations,
175//! eliminating the N+1 problem even when performing nested queries.
176//! ```
177//! # use sea_orm::{DbConn, error::*, prelude::*, entity::*, query::*, tests_cfg::*};
178//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
179//! // join paths:
180//! // user -> profile
181//! // user -> post
182//! // post -> post_tag -> tag
183//! let smart_user = user::Entity::load()
184//! .filter_by_id(42) // shorthand for .filter(user::COLUMN.id.eq(42))
185//! .with(profile::Entity) // 1-1 uses join
186//! .with((post::Entity, tag::Entity)) // 1-N uses data loader
187//! .one(db)
188//! .await?
189//! .unwrap();
190//!
191//! // 3 queries are executed under the hood:
192//! // 1. SELECT FROM user JOIN profile WHERE id = $
193//! // 2. SELECT FROM post WHERE user_id IN (..)
194//! // 3. SELECT FROM tag JOIN post_tag WHERE post_id IN (..)
195//!
196//! smart_user
197//! == user::ModelEx {
198//! id: 42,
199//! name: "Bob".into(),
200//! email: "bob@sea-ql.org".into(),
201//! profile: HasOne::Loaded(
202//! profile::ModelEx {
203//! # id: 1,
204//! picture: "image.jpg".into(),
205//! # user_id: 1,
206//! # user: HasOne::Unloaded,
207//! }
208//! .into(),
209//! ),
210//! posts: HasMany::Loaded(vec![post::ModelEx {
211//! # id: 2,
212//! # user_id: 1,
213//! title: "Nice weather".into(),
214//! # author: HasOne::Unloaded,
215//! # comments: HasMany::Unloaded,
216//! tags: HasMany::Loaded(vec![tag::ModelEx {
217//! # id: 3,
218//! tag: "diary".into(),
219//! # posts: HasMany::Unloaded,
220//! }]),
221//! }]),
222//! };
223//! # Ok(())
224//! # }
225//! ```
226//!
227//! ## Schema first or Entity first? Your choice
228//!
229//! SeaORM provides a powerful migration system that lets you create tables, modify schemas, and seed data with ease.
230//!
231//! With SeaORM 2.0, you also get a first‑class [Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/):
232//! simply define new entities or add columns to existing ones,
233//! and SeaORM will automatically detect the changes and create the new tables, columns, unique keys, and foreign keys.
234//!
235//! ```ignore
236//! // SeaORM resolves foreign key dependencies and creates the tables in topological order.
237//! // Requires the `entity-registry` and `schema-sync` feature flags.
238//! db.get_schema_registry("my_crate::entity::*").sync(db).await;
239//! ```
240//!
241//! ## Ergonomic Raw SQL
242//!
243//! Let SeaORM handle 95% of your transactional queries.
244//! For the remaining cases that are too complex to express,
245//! SeaORM still offers convenient support for writing raw SQL.
246//! ```
247//! # use sea_orm::{DbErr, DbConn};
248//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
249//! # use sea_orm::{entity::*, query::*, tests_cfg::*, raw_sql};
250//! # struct Item<'a> { name: &'a str }
251//! let item = Item { name: "Chocolate" }; // nested parameter access
252//! let ids = [2, 3, 4]; // expanded by the `..` operator
253//!
254//! let cake: Option<cake::Model> = Cake::find()
255//! .from_raw_sql(raw_sql!(
256//! Sqlite,
257//! r#"SELECT "id", "name" FROM "cake"
258//! WHERE "name" LIKE {item.name}
259//! AND "id" in ({..ids})
260//! "#
261//! ))
262//! .one(db)
263//! .await?;
264//! # Ok(())
265//! # }
266//! ```
267//!
268//! ## Basics
269//!
270//! ### Select
271//! SeaORM models 1-N and M-N relationships at the Entity level,
272//! letting you traverse many-to-many links through a junction table in a single call.
273//! ```
274//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
275//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
276//! // find all models
277//! let cakes: Vec<cake::Model> = Cake::find().all(db).await?;
278//!
279//! // find and filter
280//! let chocolate: Vec<cake::Model> = Cake::find()
281//! .filter(Cake::COLUMN.name.contains("chocolate"))
282//! .all(db)
283//! .await?;
284//!
285//! // find one model
286//! let cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;
287//! let cheese: cake::Model = cheese.unwrap();
288//!
289//! // find related models (lazy)
290//! let fruit: Option<fruit::Model> = cheese.find_related(Fruit).one(db).await?;
291//!
292//! // find related models (eager): for 1-1 relations
293//! let cake_with_fruit: Vec<(cake::Model, Option<fruit::Model>)> =
294//! Cake::find().find_also_related(Fruit).all(db).await?;
295//!
296//! // find related models (eager): works for both 1-N and M-N relations
297//! let cake_with_fillings: Vec<(cake::Model, Vec<filling::Model>)> = Cake::find()
298//! .find_with_related(Filling) // for M-N relations, two joins are performed
299//! .all(db) // rows are automatically consolidated by left entity
300//! .await?;
301//! # Ok(())
302//! # }
303//! ```
304//! ### Nested Select
305//!
306//! Partial models prevent overfetching by letting you querying only the fields
307//! you need; it also makes writing deeply nested relational queries simple.
308//! ```
309//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
310//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
311//! use sea_orm::DerivePartialModel;
312//!
313//! #[derive(DerivePartialModel)]
314//! #[sea_orm(entity = "cake::Entity")]
315//! struct CakeWithFruit {
316//! id: i32,
317//! name: String,
318//! #[sea_orm(nested)]
319//! fruit: Option<fruit::Model>, // this can be a regular or another partial model
320//! }
321//!
322//! let cakes: Vec<CakeWithFruit> = Cake::find()
323//! .left_join(fruit::Entity) // no need to specify join condition
324//! .into_partial_model() // only the columns in the partial model will be selected
325//! .all(db)
326//! .await?;
327//! # Ok(())
328//! # }
329//! ```
330//!
331//! ### Insert
332//! SeaORM's ActiveModel lets you work directly with Rust data structures and
333//! persist them through a simple API.
334//! It's easy to insert large batches of rows from different data sources.
335//! ```
336//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
337//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
338//! let apple = fruit::ActiveModel {
339//! name: Set("Apple".to_owned()),
340//! ..Default::default() // no need to set primary key
341//! };
342//!
343//! let pear = fruit::ActiveModel {
344//! name: Set("Pear".to_owned()),
345//! ..Default::default()
346//! };
347//!
348//! // insert one: Active Record style
349//! let apple = apple.insert(db).await?;
350//! apple.id == 1;
351//! # let apple = fruit::ActiveModel {
352//! # name: Set("Apple".to_owned()),
353//! # ..Default::default() // no need to set primary key
354//! # };
355//!
356//! // insert one: repository style
357//! let result = Fruit::insert(apple).exec(db).await?;
358//! result.last_insert_id == 1;
359//! # let apple = fruit::ActiveModel {
360//! # name: Set("Apple".to_owned()),
361//! # ..Default::default() // no need to set primary key
362//! # };
363//!
364//! // insert many returning last insert id
365//! let result = Fruit::insert_many([apple, pear]).exec(db).await?;
366//! result.last_insert_id == Some(2);
367//! # Ok(())
368//! # }
369//! ```
370//!
371//! ### Insert (advanced)
372//! You can take advantage of database specific features to perform upsert and idempotent insert.
373//! ```
374//! # use sea_orm::{DbConn, TryInsertResult, error::*, entity::*, query::*, tests_cfg::*};
375//! # async fn function_1(db: &DbConn) -> Result<(), DbErr> {
376//! # let apple = fruit::ActiveModel {
377//! # name: Set("Apple".to_owned()),
378//! # ..Default::default() // no need to set primary key
379//! # };
380//! # let pear = fruit::ActiveModel {
381//! # name: Set("Pear".to_owned()),
382//! # ..Default::default()
383//! # };
384//! // insert many with returning (if supported by database)
385//! let models: Vec<fruit::Model> = Fruit::insert_many([apple, pear])
386//! .exec_with_returning(db)
387//! .await?;
388//! models[0]
389//! == fruit::Model {
390//! id: 1, // database assigned value
391//! name: "Apple".to_owned(),
392//! cake_id: None,
393//! };
394//! # Ok(())
395//! # }
396//!
397//! # async fn function_2(db: &DbConn) -> Result<(), DbErr> {
398//! # let apple = fruit::ActiveModel {
399//! # name: Set("Apple".to_owned()),
400//! # ..Default::default() // no need to set primary key
401//! # };
402//! # let pear = fruit::ActiveModel {
403//! # name: Set("Pear".to_owned()),
404//! # ..Default::default()
405//! # };
406//! // insert with ON CONFLICT on primary key do nothing, with MySQL specific polyfill
407//! let result = Fruit::insert_many([apple, pear])
408//! .on_conflict_do_nothing()
409//! .exec(db)
410//! .await?;
411//!
412//! matches!(result, TryInsertResult::Conflicted);
413//! # Ok(())
414//! # }
415//! ```
416//!
417//! ### Update
418//! ActiveModel avoids race conditions by updating only the fields you've changed,
419//! never overwriting untouched columns.
420//! You can also craft complex bulk update queries with a fluent query building API.
421//! ```
422//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
423//! use sea_orm::sea_query::{Expr, Value};
424//!
425//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
426//! let pear: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;
427//! let mut pear: fruit::ActiveModel = pear.unwrap().into();
428//!
429//! pear.name = Set("Sweet pear".to_owned()); // update value of a single field
430//!
431//! // update one: only changed columns will be updated
432//! let pear: fruit::Model = pear.update(db).await?;
433//!
434//! // update many: UPDATE "fruit" SET "cake_id" = "cake_id" + 2
435//! // WHERE "fruit"."name" LIKE '%Apple%'
436//! Fruit::update_many()
437//! .col_expr(fruit::COLUMN.cake_id, fruit::COLUMN.cake_id.add(2))
438//! .filter(fruit::COLUMN.name.contains("Apple"))
439//! .exec(db)
440//! .await?;
441//! # Ok(())
442//! # }
443//! ```
444//! ### Save
445//! You can perform "insert or update" operation with ActiveModel, making it easy to compose transactional operations.
446//! ```
447//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
448//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
449//! let banana = fruit::ActiveModel {
450//! id: NotSet,
451//! name: Set("Banana".to_owned()),
452//! ..Default::default()
453//! };
454//!
455//! // create, because primary key `id` is `NotSet`
456//! let mut banana = banana.save(db).await?;
457//!
458//! banana.id == Unchanged(2);
459//! banana.name = Set("Banana Mongo".to_owned());
460//!
461//! // update, because primary key `id` is present
462//! let banana = banana.save(db).await?;
463//! # Ok(())
464//! # }
465//! ```
466//! ### Delete
467//! The same ActiveModel API consistent with insert and update.
468//! ```
469//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};
470//! # async fn function(db: &DbConn) -> Result<(), DbErr> {
471//! // delete one: Active Record style
472//! let orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;
473//! let orange: fruit::Model = orange.unwrap();
474//! orange.delete(db).await?;
475//!
476//! // delete one: repository style
477//! let orange = fruit::ActiveModel {
478//! id: Set(2),
479//! ..Default::default()
480//! };
481//! fruit::Entity::delete(orange).exec(db).await?;
482//!
483//! // delete many: DELETE FROM "fruit" WHERE "fruit"."name" LIKE '%Orange%'
484//! fruit::Entity::delete_many()
485//! .filter(fruit::COLUMN.name.contains("Orange"))
486//! .exec(db)
487//! .await?;
488//!
489//! # Ok(())
490//! # }
491//! ```
492//! ### Raw SQL Query
493//! The `raw_sql!` macro is like the `format!` macro but without the risk of SQL injection.
494//! It supports nested parameter interpolation, array and tuple expansion, and even repeating group,
495//! offering great flexibility in crafting complex queries.
496//!
497//! ```
498//! # use sea_orm::{DbErr, DbConn};
499//! # async fn functio(db: &DbConn) -> Result<(), DbErr> {
500//! # use sea_orm::{query::*, FromQueryResult, raw_sql};
501//! #[derive(FromQueryResult)]
502//! struct CakeWithBakery {
503//! name: String,
504//! #[sea_orm(nested)]
505//! bakery: Option<Bakery>,
506//! }
507//!
508//! #[derive(FromQueryResult)]
509//! struct Bakery {
510//! #[sea_orm(alias = "bakery_name")]
511//! name: String,
512//! }
513//!
514//! let cake_ids = [2, 3, 4]; // expanded by the `..` operator
515//!
516//! // can use many APIs with raw SQL, including nested select
517//! let cake: Option<CakeWithBakery> = CakeWithBakery::find_by_statement(raw_sql!(
518//! Sqlite,
519//! r#"SELECT "cake"."name", "bakery"."name" AS "bakery_name"
520//! FROM "cake"
521//! LEFT JOIN "bakery" ON "cake"."bakery_id" = "bakery"."id"
522//! WHERE "cake"."id" IN ({..cake_ids})"#
523//! ))
524//! .one(db)
525//! .await?;
526//! # Ok(())
527//! # }
528//! ```
529//!
530//! ## 🧭 Seaography: instant GraphQL API
531//!
532//! [Seaography](https://github.com/SeaQL/seaography) is a GraphQL framework built for SeaORM.
533//! Seaography allows you to build GraphQL resolvers quickly.
534//! With just a few commands, you can launch a fullly-featured GraphQL server from SeaORM entities,
535//! complete with filter, pagination, relational queries and mutations!
536//!
537//! Look at the [Seaography Example](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) to learn more.
538//!
539//! <img src="https://raw.githubusercontent.com/SeaQL/sea-orm/master/examples/seaography_example/Seaography%20example.png"/>
540//!
541//! ## 🖥️ SeaORM Pro: Professional Admin Panel
542//!
543//! [SeaORM Pro](https://github.com/SeaQL/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!
544//!
545//! SeaORM Pro has been updated to support the latest features in SeaORM 2.0.
546//!
547//! Features:
548//!
549//! + Full CRUD
550//! + Built on React + GraphQL
551//! + Built-in GraphQL resolver
552//! + Customize the UI with TOML config
553//! + Role Based Access Control *(new in 2.0)*
554//!
555//! Learn More
556//!
557//! + [Example Repo](https://github.com/SeaQL/sea-orm-pro)
558//! + [Getting Started](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started/)
559//!
560//! 
561//! 
562//!
563//! ## SQL Server Support
564//!
565//! [SQL Server for SeaORM](https://www.sea-ql.org/SeaORM-X/) offers the same SeaORM API for MSSQL. We ported all test cases and examples, complemented by MSSQL specific documentation. If you are building enterprise software, you can [request commercial access](https://forms.office.com/r/1MuRPJmYBR). It is currently based on SeaORM 1.0, but we will offer free upgrade to existing users when SeaORM 2.0 is finalized.
566//!
567//! ## Releases
568//!
569//! SeaORM 2.0 has reached its release candidate phase. We'd love for you to try it out and help shape the final release by [sharing your feedback](https://github.com/SeaQL/sea-orm/discussions/2548).
570//!
571//! SeaORM 2.0 is shaping up to be our most significant release yet - with a few breaking changes, plenty of enhancements, and a clear focus on developer experience.
572//!
573//! + [A Sneak Peek at SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-16-sea-orm-2.0/)
574//! + [SeaORM 2.0: A closer look](https://www.sea-ql.org/blog/2025-09-24-sea-orm-2.0/)
575//! + [Role Based Access Control in SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-30-sea-orm-rbac/)
576//! + [Seaography 2.0: A Powerful and Extensible GraphQL Framework](https://www.sea-ql.org/blog/2025-10-08-seaography/)
577//! + [SeaORM 2.0: New Entity Format](https://www.sea-ql.org/blog/2025-10-20-sea-orm-2.0/)
578//! + [SeaORM 2.0: Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/)
579//!
580//! If you make extensive use of SeaQuery, we recommend checking out our blog post on SeaQuery 1.0 release:
581//!
582//! + [The road to SeaQuery 1.0](https://www.sea-ql.org/blog/2025-08-30-sea-query-1.0/)
583//!
584//! It doesn't mean that SeaORM is 'done', we've designed an architecture to allow us to deliver new features without major breaking changes.
585//!
586//! + [Change Log](https://github.com/SeaQL/sea-orm/tree/master/CHANGELOG.md)
587//!
588//! ## License
589//!
590//! Licensed under either of
591//!
592//! - Apache License, Version 2.0
593//! ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
594//! - MIT license
595//! ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
596//!
597//! at your option.
598//!
599//! ## Contribution
600//!
601//! Unless you explicitly state otherwise, any contribution intentionally submitted
602//! for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
603//! dual licensed as above, without any additional terms or conditions.
604//!
605//! We invite you to participate, contribute and together help build Rust's future.
606//!
607//! A big shout out to our contributors!
608//!
609//! [](https://github.com/SeaQL/sea-orm/graphs/contributors)
610//!
611//! ## Who's using SeaORM?
612//!
613//! SeaORM is trusted by companies and startups for both internal tools and public‑facing applications, thanks to its ergonomics and the familiarity it brings from dynamic languages.
614//! Built on async Rust, it combines high performance and a strong type system without sacrificing developer productivity.
615//!
616//! 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!
617//!
618//! | Project | GitHub | Tagline |
619//! |---------|--------|---------|
620//! | [Zed](https://github.com/zed-industries/zed) |  | A high-performance, multiplayer code editor |
621//! | [OpenObserve](https://github.com/openobserve/openobserve) |  | Open-source observability platform |
622//! | [RisingWave](https://github.com/risingwavelabs/risingwave) |  | Stream processing and management platform |
623//! | [LLDAP](https://github.com/nitnelave/lldap) |  | A light LDAP server for user management |
624//! | [Warpgate](https://github.com/warp-tech/warpgate) |  | Smart SSH bastion that works with any SSH client |
625//! | [Svix](https://github.com/svix/svix-webhooks) |  | The enterprise ready webhooks service |
626//! | [Ryot](https://github.com/IgnisDa/ryot) |  | The only self hosted tracker you will ever need |
627//! | [Lapdev](https://github.com/lapce/lapdev) |  | Self-hosted remote development enviroment |
628//! | [System Initiative](https://github.com/systeminit/si) |  | DevOps Automation Platform |
629//! | [OctoBase](https://github.com/toeverything/OctoBase) |  | A light-weight, scalable, offline collaborative data backend |
630//!
631//! ## Sponsorship
632//!
633//! [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.
634//!
635//! ### Gold Sponsors
636//!
637//! <table><tr>
638//! <td><a href="https://qdx.co/">
639//! <img src="https://www.sea-ql.org/static/sponsors/QDX.svg" width="138"/>
640//! </a></td>
641//! </tr></table>
642//!
643//! [QDX](https://qdx.co/) pioneers quantum dynamics-powered drug discovery, leveraging AI and supercomputing to accelerate molecular modeling.
644//! We're immensely grateful to QDX for sponsoring the development of SeaORM, the SQL toolkit that powers their data engineering workflows.
645//!
646//! ### Silver Sponsors
647//!
648//! We're grateful to our silver sponsors: Digital Ocean, for sponsoring our servers. And JetBrains, for sponsoring our IDE.
649//!
650//! <table><tr>
651//! <td><a href="https://www.digitalocean.com/">
652//! <img src="https://www.sea-ql.org/static/sponsors/DigitalOcean.svg" width="125">
653//! </a></td>
654//!
655//! <td><a href="https://www.jetbrains.com/">
656//! <img src="https://www.sea-ql.org/static/sponsors/JetBrains.svg" width="125">
657//! </a></td>
658//! </tr></table>
659//!
660//! ## Mascot
661//!
662//! A friend of Ferris, Terres the hermit crab is the official mascot of SeaORM. His hobby is collecting shells.
663//!
664//! <img alt="Terres" src="https://www.sea-ql.org/SeaORM/img/Terres.png" width="400"/>
665//!
666//! ## 🦀 Rustacean Sticker Pack
667//! The Rustacean Sticker Pack is the perfect way to express your passion for Rust. Our stickers are made with a premium water-resistant vinyl with a unique matte finish.
668//!
669//! Sticker Pack Contents:
670//!
671//! + Logo of SeaQL projects: SeaQL, SeaORM, SeaQuery, Seaography
672//! + Mascots: Ferris the Crab x 3, Terres the Hermit Crab
673//! + The Rustacean wordmark
674//!
675//! [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.
676//!
677//! <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>
678#![doc(
679 html_logo_url = "https://raw.githubusercontent.com/SeaQL/sea-query/master/docs/SeaQL icon dark.png"
680)]
681
682mod database;
683mod docs;
684mod driver;
685pub mod dynamic;
686/// Module for the Entity type and operations
687pub mod entity;
688/// Error types for all database operations
689pub mod error;
690/// This module performs execution of queries on a Model or ActiveModel
691mod executor;
692/// Types and methods to perform metric collection
693pub mod metric;
694/// Types and methods to perform queries
695pub mod query;
696#[cfg(feature = "rbac")]
697#[cfg_attr(docsrs, doc(cfg(feature = "rbac")))]
698pub mod rbac;
699/// Types that defines the schemas of an Entity
700pub mod schema;
701/// Helpers for working with Value
702pub mod value;
703
704#[doc(hidden)]
705#[cfg(all(feature = "macros", feature = "tests-cfg"))]
706pub mod tests_cfg;
707mod util;
708
709pub use database::*;
710#[allow(unused_imports)]
711pub use driver::*;
712pub use entity::*;
713pub use error::*;
714pub use executor::*;
715pub use query::*;
716pub use schema::*;
717
718#[cfg(feature = "macros")]
719pub use sea_orm_macros::{
720 DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveDisplay,
721 DeriveEntity, DeriveEntityModel, DeriveIden, DeriveIntoActiveModel, DeriveMigrationName,
722 DeriveModel, DeriveModelEx, DerivePartialModel, DerivePrimaryKey, DeriveRelatedEntity,
723 DeriveRelation, DeriveValueType, FromJsonQueryResult, FromQueryResult, raw_sql,
724 sea_orm_compact_model as compact_model, sea_orm_model as model,
725};
726
727pub use sea_query;
728pub use sea_query::Iden;
729
730pub use sea_orm_macros::EnumIter;
731pub use strum;
732
733#[cfg(feature = "sqlx-dep")]
734pub use sqlx;