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