sea-query-derive
Derive macro for sea-query's Iden trait
1.0.0
16M downloads/mo
#2366 most downloaded on crates.io
SeaQL/sea-query
What this package is like to depend on
Last release 2 months ago
28 May 2026
Release timing varies
gaps range from 1 weeks to 1.3 years
Some releases are documented
notes for 3 of 10 stable releases
1 version withdrawn
withdrawn after publishing
6 years old
17 releases · first in 2021
3 releases in the last 12 months
see the full history below
Release timeline
17 releases · Feb 2021 to May 2026Releases
latest 17-
1.0.028 May 2026Release notes
Open source →(since 1.0.0-rc.34)
Highlights
- Published the stable
sea-query 1.0.0release. - Published the companion crates as final non-rc versions.
- Updated the SQLx binder crate for SQLx 0.9.
- Fixed PostgreSQL array handling for null array elements.
- Fixed tokenizer handling of backend-specific backslash escaping.
- Updated README and examples from rc dependencies to the stable
1.0dependency line.
Breaking Changes
The SQLx binder line for SeaQuery 1.0 now targets SQLx 0.9. Users staying on SQLx 0.8 should use
sea-query-sqlx 0.8.1; users on SQLx 0.9 should usesea-query-sqlx 0.9.0.# SQLx 0.8 compatibility line sea-query-sqlx = "0.8.1" # SQLx 0.9 line sea-query-sqlx = "0.9.1"
SQLx feature wiring was updated for the SQLx 0.9 runtime and TLS feature split. SeaQuery now exposes explicit TLS feature flags such as
tls-none,tls-native-tls,tls-rustls, and the rustls provider variants. The older combined runtime/TLS feature names remain available as compatibility aliases.- Temporarily gated Jiff SQLx binders on SQLx 0.9
Jiff SQLx binders were temporarily disabled because
jiff-sqlxstill targeted SQLx 0.8 at the time of the SeaQuery 1.0.0 release. Enabling Jiff values with SQLx 0.9 may panic for unsupported Jiff argument binding.Stable Crate Versions
Use these stable companion crate versions with
sea-query 1.0.0:sea-query 1.0.0sea-query-derive 1.0.0sea-query-rusqlite 0.8.0sea-query-postgres 0.6.0sea-query-diesel 0.3.0sea-query-rbatis 0.2.0
sea-query = "1.0" sea-query-derive = "1.0" sea-query-rusqlite = "0.8" sea-query-postgres = "0.6" sea-query-diesel = "0.3" sea-query-rbatis = "0.2"
Fixes
- Fixed null element handling in PostgreSQL arrays #1068
PostgreSQL array values can now contain null elements without panicking during conversion. This fixes
Value::Arrayconversion paths where arrays contain null values.- Fixed tokenizer handling of backend-specific backslash escaping
The tokenizer now distinguishes MySQL, PostgreSQL, and SQLite string escaping rules. In particular, PostgreSQL backslash escaping is handled only for escape strings, avoiding incorrect parsing around single quotes and backslashes.
Dependency Updates
- Removed the
inherentdependency from the main crate. - Aligned
ipnetworkto0.21.1across SeaQuery and binder crates. - Updated
sea-query-postgres-typesto0.1.1. - Raised binder crate Rust versions to Rust
1.88.0where needed.
Documentation And Tests
- Updated README installation snippets from rc versions to stable versions.
- Updated SQLx examples for MySQL, PostgreSQL, and SQLite.
- Added regression coverage for null PostgreSQL array elements.
- Added tokenizer tests for backend-specific backslash escaping.
Migration Notes
- Use
sea-query-sqlx 0.8.1if your application still depends on SQLx 0.8. - Use
sea-query-sqlx 0.9.0with SQLx 0.9. - Review SQLx feature flags if your application used the old combined runtime/TLS feature names.
- Avoid enabling Jiff SQLx binding with SQLx 0.9 until
jiff-sqlxsupport is available for SQLx 0.9.
Release notes
Open source →- 1.0.0 - Stable SeaQuery 1.0 release notes
Release Candidates
- 1.0.0-rc.34 — Table partitioning, Jiff binder support,
JSON_TABLErefactor - 1.0.0-rc.33 —
Value::Enum, Postgres advisory locks,SelectExprTrait - 1.0.0-rc.32 —
EXPLAIN,FILTERon aggregates,ALTER TABLE DROP CONSTRAINT - 1.0.0-rc.31 —
SELECT INTO,eq_any/ne_all,Value::array_type - 1.0.0-rc.30 — Tokenizer comment parsing, dependency reductions
- 1.0.0-rc.29 — Legacy
serialoption for Postgres - 1.0.0-rc.28 — Restore Value system
- 1.0.0-rc.27 — Revert
impl Iden for String - 1.0.0-rc.26 —
From<Vec<Value>> for Array,FromIterator<T> for Array - 1.0.0-rc.24 — Array API redesign
- 1.0.0-rc.23 —
Value::Enum,ON CONFLICT ON CONSTRAINT, CTEVALUESclause - 1.0.0-rc.22 — Index operator class,
DROP COLUMN IF EXISTS, nullable values - 1.0.0-rc.20 —
ValueTupleIter, SQLite decimal fix
New features
- Support
EXPLAINstatements https://github.com/SeaQL/sea-query/pull/1044 #![forbid(unsafe_code)]in all workspace crates https://github.com/SeaQL/sea-query/pull/930- Unify
ExprandSimpleExpras one type.SimpleExpris kept as an alias ofExpr, but they can now be used interchangeably. There may be a few compile errors and some clippy warnings, basically just remove the redundant.into()https://github.com/SeaQL/sea-query/pull/889
pub type SimpleExpr = Expr; // ! impl From<Expr> for SimpleExpr { .. } // now removed- New
Identype system. Previously,DynIdenis an alias toSeaRc<dyn Iden>, and is lazily rendered. Now, it's anCow<'static, str>, and is eagerly rendered.SeaRcis no longer an alias toRc/Arc, now is only a unit struct. As such,Send/Syncis no longer needed. It's still possible to dynamically serialize a String as identifier, see example usage. https://github.com/SeaQL/sea-query/pull/909
pub type DynIden = SeaRc<dyn Iden>; // old pub struct DynIden(pub(crate) Cow<'static, str>); // new pub struct SeaRc<I>(pub(crate) RcOrArc<I>); // old pub struct SeaRc; // new- Reworked
TableRefandColumnRefvariants https://github.com/SeaQL/sea-query/pull/927
// the following variants are collapsed into one: enum TableRef { Table(DynIden), SchemaTable(DynIden, DynIden), DatabaseSchemaTable(DynIden, DynIden, DynIden), TableAlias(DynIden, DynIden), SchemaTableAlias(DynIden, DynIden, DynIden), DatabaseSchemaTableAlias(DynIden, DynIden, DynIden, DynIden), .. } // now it's just: enum TableRef { Table(TableName, Option<DynIden>), // optional Alias .. } pub struct DatabaseName(pub DynIden); pub struct SchemaName(pub Option<DatabaseName>, pub DynIden); /// A table name, potentially qualified as [database.][schema.]table pub struct TableName(pub Option<SchemaName>, pub DynIden);// before enum ColumnRef { Column(DynIden), TableColumn(DynIden, DynIden), SchemaTableColumn(DynIden, DynIden, DynIden), Asterisk, TableAsterisk(DynIden), } // now enum ColumnRef { /// A column name, potentially qualified as [database.][schema.][table.]column Column(ColumnName), /// An `*` expression, potentially qualified as [database.][schema.][table.]* Asterisk(Option<TableName>), } pub struct ColumnName(pub Option<TableName>, pub DynIden);Enhancements
- Supports Jiff types except
jiff::Zoned. At the moment this support is only available through the SQLx binder. When using SQLx with multiple backends, enableunimplemented-jiff-sqlx-mysqlto suppress the compile-time error. After enabling it, runtime panics may occur. - Add
Expr::not_existshttps://github.com/SeaQL/sea-query/pull/983 - Add
serdefeature. Currently, enabling it allowsValueto be serializable https://github.com/SeaQL/sea-query/pull/966 - Add
Keyword::Defaulthttps://github.com/SeaQL/sea-query/pull/965 - Enable
clippy::nurseryhttps://github.com/SeaQL/sea-query/pull/938 - Removed unnecessary
'staticbounds from type signatures https://github.com/SeaQL/sea-query/pull/921 cast_as_quotednow allows you to qualify the type name. https://github.com/SeaQL/sea-query/pull/922
let query = Query::select() .expr(Func::cast_as_quoted("hello", ("MySchema", "MyType"))) .to_owned(); assert_eq!( query.to_string(PostgresQueryBuilder), r#"SELECT CAST('hello' AS "MySchema"."MyType")"# );- Most
Valuevariants are now unboxed (exceptBigDecimalandArray). Previously the size is 24 bytes. https://github.com/SeaQL/sea-query/pull/925
assert_eq!(std::mem::size_of::<Value>(), 32);- Merged
Func/FunctionandPgFunc/PgFunction. Now the latter is just an alias of the former https://github.com/SeaQL/sea-query/pull/944
// old condition.add(Func::lower(Expr::col(column)).eq(SimpleExpr::FunctionCall(Func::lower(value)))) // new condition.add(Func::lower(Expr::col(*column)).eq(Func::lower(value)));impl From<Expr> for Condition. Now you can useExprinstead ofConditionExpression, which has been removed from the public API https://github.com/SeaQL/sea-query/pull/915
Cond::all().add(ConditionExpression::Expr(Expr::new(..))) // old Cond::all().add(Expr::new(..)) // new- Replaced
serialwithGENERATED BY DEFAULT AS IDENTITY(Postgres) https://github.com/SeaQL/sea-query/pull/918 To restore legacy behaviour, you can enable theoption-postgres-use-serialfeature flag
let table = Table::create() .table(Char::Table) .col(ColumnDef::new(Char::Id).integer().not_null().auto_increment().primary_key()) .to_owned(); assert_eq!( table.to_string(PostgresQueryBuilder), [ r#"CREATE TABLE "character" ("#, r#""id" integer GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY,"#, r#")"#, ].join(" ") ); // if you needed to support legacy system you can still do: let table = Table::create() .table(Char::Table) .col(ColumnDef::new(Char::Id).custom("serial").not_null().primary_key()) .to_owned(); assert_eq!( table.to_string(PostgresQueryBuilder), [ r#"CREATE TABLE "character" ("#, r#""id" serial NOT NULL PRIMARY KEY"#, r#")"#, ].join(" ") );Breaking Changes
- Removed inherent
SimpleExprmethods that duplicateExprTrait. If you encounter the following error, please adduse sea_query::ExprTraitin scope https://github.com/SeaQL/sea-query/pull/890
error[E0599]: no method named `like` found for enum `sea_query::Expr` in the current scope | | Expr::col((self.entity_name(), *self)).like(s) | | fn like<L>(self, like: L) -> Expr | ---- the method is available for `sea_query::Expr` here | = help: items from traits can only be used if the trait is in scope help: trait `ExprTrait` which provides `like` is implemented but not in scope; perhaps you want to import it | -> + use sea_query::ExprTrait;error[E0308]: mismatched types --> src/sqlite/discovery.rs:27:57 | | .and_where(Expr::col(Alias::new("type")).eq("table")) | -- ^^^^^^^ expected `&Expr`, found `&str` | | | arguments to this method are incorrect | = note: expected reference `&sea_query::Expr` found reference `&'static str`- Added
non_exhaustiveto AST enums. It allows us to add new features and extend the AST without breaking the API. If you encounter the following error, please add a wildcard match_ => {..}https://github.com/SeaQL/sea-query/pull/891
error[E0004]: non-exhaustive patterns: `&_` not covered | | match table_ref { | ^^^^^^^^^ pattern `&_` not covered | note: `TableRef` defined here | | pub enum TableRef { | ^^^^^^^^^^^^^^^^^ = note: the matched value is of type `&TableRef` = note: `TableRef` is marked as non-exhaustive, so a wildcard `_` is necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | | TableRef::FunctionCall(_, tbl) => SeaRc::clone(tbl), -> | &_ => todo!(),ExprTrait::eqcollided withstd::cmp::Eq. If you encounter the following error, please usestd::cmp::PartialEq::eq(a, b)orsea_query::ExprTrait::eq(a, b)explicitly https://github.com/SeaQL/sea-query/pull/890
error[E0308]: mismatched types | | fn eq(&self, other: &Self) -> bool { | ---- expected `bool` because of return type | format!("{:?}", self.0).eq(&format!("{:?}", other.0)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `Expr` For more information about this error, try `rustc --explain E0308`. error: could not compile `seaography` (lib) due to 1 previous error- The method signature of
Iden::unquotedis changed. If you're implementingIdenmanually, you can modify it like below https://github.com/SeaQL/sea-query/pull/909
error[E0050]: method `unquoted` has 2 parameters but the declaration in trait `types::Iden::unquoted` has 1 --> src/tests_cfg.rs:31:17 | | fn unquoted(&self, s: &mut dyn std::fmt::Write) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 parameter, found 2 | ::: src/types.rs:63:17 | | fn unquoted(&self) -> &str; | ----- trait requires 1 parameterimpl Iden for Glyph { - fn unquoted(&self, s: &mut dyn fmt::Write) { + fn unquoted(&self) -> &str { - write!( - s, - "{}", match self { Self::Table => "glyph", Self::Id => "id", Self::Tokens => "tokens", } - ) - .unwrap(); } }- Removed
ConditionExpressionfrom the public API. Instead, just convert betweenConditionandExprusingFrom/Intohttps://github.com/SeaQL/sea-query/pull/915
error[E0603]: enum `ConditionExpression` is private --> tests/mysql/query.rs:734:20 | > | use sea_query::ConditionExpression; | ^^^^^^^^^^^^^^^^^^^ private enum > | Cond::all().add(ConditionExpression::Expr(Expr::new( | ^^^^^^^^^^^^^^^^^^^ use of undeclared type `ConditionExpression`Simply do the following:
Cond::all().add(Expr::new(..))- Reworked
ColumnRefvariants may cause compile error.
error[E0277]: the trait bound `fn(std::option::Option<TableName>) -> sea_query::ColumnRef {sea_query::ColumnRef::Asterisk}: IntoColumnRef` is not satisfied --> src/executor/query.rs:1599:21 | > | .column(ColumnRef::Asterisk) | ------ ^^^^^^^^^^^^^^^^^^^ the trait `sea_query::Iden` is not implemented for fn item `fn(std::option::Option<TableName>) -> sea_query::ColumnRef {sea_query::ColumnRef::Asterisk}` | | | required by a bound introduced by this call error[E0308]: mismatched types --> src/executor/query.rs:1607:54 | > | SimpleExpr::Column(ColumnRef::Column("id".into_iden())) | ----------------- ^^^^^^^^^^^^^^^^ expected `ColumnName`, found `DynIden` | | | arguments to this enum variant are incorrectIn the former case
Asteriskhas an additional innerOption<TableName>, you can simply putNone..column(ColumnRef::Asterisk(None))In the latter case,
&'static strcan now be used in most methods that acceptsColumnRef.Expr::column("id")- Reworked
TableRefvariants may cause compile error.
error[E0061]: this enum variant takes 2 arguments but 1 argument was supplied --> src/entity/relation.rs:526:15 | > | from_tbl: TableRef::Table("foo".into_iden()), | ^^^^^^^^^^^^^^^------------------- | || | |expected `TableName`, found `DynIden` | argument #2 of type `Option<DynIden>` is missingIt's recommended to use the
IntoTableReftrait to convert types instead of constructing AST manually.use sea_orm::sea_query::IntoTableRef; from_tbl: "foo".into_table_ref(),- Replace
dyn <Trait>withimpl <Trait>https://github.com/SeaQL/sea-query/pull/982 This gained us up to 10% performance, however it does meandyn QueryBuilderis no longer possible.
Minor breaking changes
-
Changed
Into*traits (likeIntoCondition) to be defined astrait IntoCondition: Into<Condition>and implemented for allT: Into<Condition>. NowIntoConditionandInto<Condition>are completely interchangable. But you can still use.into_condition()for readability.If you have manually implemented
Into*traits, it may cause conflicts. You should rewrite your impls as asimpl From<..> for Condition.Full list of changed traits:
IntoColumnDefhttps://github.com/SeaQL/sea-query/pull/975IntoColumnRefhttps://github.com/SeaQL/sea-query/pull/959IntoConditionhttps://github.com/SeaQL/sea-query/pull/939IntoIdenhttps://github.com/SeaQL/sea-query/pull/973IntoIndexColumnhttps://github.com/SeaQL/sea-query/pull/976IntoLikeExprhttps://github.com/SeaQL/sea-query/pull/974IntoTableRefhttps://github.com/SeaQL/sea-query/pull/958IntoTypeRefhttps://github.com/SeaQL/sea-query/pull/969IntoValueTuplehttps://github.com/SeaQL/sea-query/pull/960
-
Unboxed
Valuevariants may cause compile error. Simply remove theBoxin these cases https://github.com/SeaQL/sea-query/pull/925
error[E0308]: mismatched types --> /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sea-schema-0.17.0-rc.3/src/sqlite/def/table.rs:248:59 | > | Value::String(Some(Box::new(string_value.to_string())))); | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `String`, found `Box<String>` | | | arguments to this enum variant are incorrect-
Blanket-implemented
SqliteExprandPgExprforT where T: ExprTraithttps://github.com/SeaQL/sea-query/pull/914Now you can use database-specific operators with all expression types. If you had custom implementations in your own code, some may no longer compile and may need to be deleted.
-
Replaced
ColumnSpec::Check(Expr)withColumnSpec::Check(Check)to support named check constraints https://github.com/SeaQL/sea-query/pull/920 -
SelectStatement::cross_joinno longer accepts a condition https://github.com/SeaQL/sea-query/pull/956 -
Turned
TypeReffrom an enum into a struct that reusesTableName. https://github.com/SeaQL/sea-query/pull/969 -
Changed
Expr::TypeName(DynIden)toExpr::TypeName(TypeRef), which can be qualified.If you manually construct this variant and it no longer compiles, just add
.into(). -
Renamed
QueryBuilder::prepare_simple_exprtoprepare_exprhttps://github.com/SeaQL/sea-query/pull/988 -
Changed signature of
Expr::Customhttps://github.com/SeaQL/sea-query/pull/940
enum Expr { - Custom(String), + Custom(Cow<'static, str>), } fn cust<T>(s: T) -> Self where - T: Into<String>, + T: Into<Cow<'static, str>>, { Self::Custom(s.into()) }You many encounter the following error:
| let sql = self.sql.trim(); | ^^^^^^^^ borrowed value does not live long enough ... | Expr::cust_with_values(sql, values.0) | ------------------------------------- argument requires that `self.stmt.sql` is borrowed for `'static`Simply convert the
&strtoString:let sql = self.sql.trim().to_owned();Bug Fixes
- Removed invalid condition requirement on
SelectStatement::cross_joinhttps://github.com/SeaQL/sea-query/pull/956
Upgrades
- Upgraded to Rust Edition 2024 https://github.com/SeaQL/sea-query/pull/885
Maintainence
sea-query-binderhas been superseded withsea-query-sqlx
- Published the stable
-
1.0.0-rc.1226 Jan 2026 pre-releaseNothing published for this version
-
1.0.0-rc.1125 Oct 2025 pre-releaseNothing published for this version
-
1.0.0-rc.912 Aug 2025 pre-releaseNothing published for this version
-
1.0.0-rc.807 Aug 2025 pre-releaseNothing published for this version
-
1.0.0-rc.701 Aug 2025 pre-releaseNothing published for this version
-
1.0.0-rc.519 Jul 2025 pre-releaseNothing published for this version
-
0.4.316 Mar 2025Nothing published for this version
-
0.4.205 Oct 2024Nothing published for this version
-
0.4.119 Oct 2023Nothing published for this version
-
0.4.012 Jul 2023Release notes
Open source →- Added JSON binary column type
ColumnDef::json_binary() - Custom column type
ColumnDef::custom()
- Added JSON binary column type
-
0.3.112 Jul 2023 withdrawnNothing published for this version
-
0.3.009 Dec 2022Nothing published for this version
-
0.2.010 Aug 2021Nothing published for this version
-
0.1.208 Apr 2021Nothing published for this version
-
0.1.105 Apr 2021Nothing published for this version
-
0.1.009 Feb 2021