NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #2366 most downloaded on crates.io
Derive macro for sea-query's Iden trait
Last release 4 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
One column per quarter.
Published the stable sea-query 1.0.0 release.
(since 1.0.0-rc.34)
sea-query 1.0.0 release.1.0 dependency line.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 use sea-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.
Jiff SQLx binders were temporarily disabled because jiff-sqlx still 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.
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.0sea-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"PostgreSQL array values can now contain null elements without panicking during conversion. This fixes Value::Array conversion paths where arrays contain null values.
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.
inherent dependency from the main crate.ipnetwork to 0.21.1 across SeaQuery and binder crates.sea-query-postgres-types to 0.1.1.1.88.0 where needed.sea-query-sqlx 0.8.1 if your application still depends on SQLx 0.8.sea-query-sqlx 0.9.0 with SQLx 0.9.jiff-sqlx support is available for SQLx 0.9.JSON_TABLE refactorValue::Enum, Postgres advisory locks, SelectExprTraitEXPLAIN, FILTER on aggregates, ALTER TABLE DROP CONSTRAINTSELECT INTO, eq_any/ne_all, Value::array_typeserial option for Postgresimpl Iden for StringFrom<Vec<Value>> for Array, FromIterator<T> for ArrayValue::Enum, ON CONFLICT ON CONSTRAINT, CTE VALUES clauseDROP COLUMN IF EXISTS, nullable valuesValueTupleIter, SQLite decimal fixEXPLAIN statements https://github.com/SeaQL/sea-query/pull/1044#![forbid(unsafe_code)] in all workspace crates https://github.com/SeaQL/sea-query/pull/930Expr and SimpleExpr as one type. SimpleExpr is kept as an alias of Expr, 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/889pub type SimpleExpr = Expr; // !
impl From<Expr> for SimpleExpr { .. } // now removed
Iden type system. Previously, DynIden is an alias to SeaRc<dyn Iden>, and is lazily rendered. Now, it's an Cow<'static, str>, and is eagerly rendered. SeaRc is no longer an alias to Rc / Arc, now is only a unit struct. As such, Send / Sync is no longer needed. It's still possible to dynamically serialize a String as identifier, see example usage. https://github.com/SeaQL/sea-query/pull/909pub 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
TableRef and ColumnRef variants 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);
jiff::Zoned.
At the moment this support is only available through the SQLx binder.
When using SQLx with multiple backends, enable unimplemented-jiff-sqlx-mysql to suppress the
compile-time error. After enabling it, runtime panics may occur.Expr::not_exists https://github.com/SeaQL/sea-query/pull/983serde feature. Currently, enabling it allows Value to be serializable https://github.com/SeaQL/sea-query/pull/966Keyword::Default https://github.com/SeaQL/sea-query/pull/965clippy::nursery https://github.com/SeaQL/sea-query/pull/938'static bounds from type signatures https://github.com/SeaQL/sea-query/pull/921cast_as_quoted now allows you to qualify the type name. https://github.com/SeaQL/sea-query/pull/922let 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")"#
);
Value variants are now unboxed (except BigDecimal and Array). Previously the size is 24 bytes. https://github.com/SeaQL/sea-query/pull/925assert_eq!(std::mem::size_of::<Value>(), 32);
Func/Function and PgFunc/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 use Expr instead of ConditionExpression, which has been removed from the public API https://github.com/SeaQL/sea-query/pull/915Cond::all().add(ConditionExpression::Expr(Expr::new(..))) // old
Cond::all().add(Expr::new(..)) // new
serial with GENERATED BY DEFAULT AS IDENTITY (Postgres) https://github.com/SeaQL/sea-query/pull/918
To restore legacy behaviour, you can enable the option-postgres-use-serial feature flaglet 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(" ")
);
SimpleExpr methods that duplicate ExprTrait. If you encounter the following error, please add use sea_query::ExprTrait in scope https://github.com/SeaQL/sea-query/pull/890error[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`
non_exhaustive to 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/891error[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::eq collided with std::cmp::Eq. If you encounter the following error, please use std::cmp::PartialEq::eq(a, b) or
sea_query::ExprTrait::eq(a, b) explicitly https://github.com/SeaQL/sea-query/pull/890error[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
Iden::unquoted is changed. If you're implementing Iden manually, you can modify it like below https://github.com/SeaQL/sea-query/pull/909error[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 parameter
impl 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();
}
}
ConditionExpression from the public API. Instead, just convert between Condition and Expr using From/Into https://github.com/SeaQL/sea-query/pull/915error[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(..))
ColumnRef variants 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 incorrect
In the former case Asterisk has an additional inner Option<TableName>, you can simply put None.
.column(ColumnRef::Asterisk(None))
In the latter case, &'static str can now be used in most methods that accepts ColumnRef.
Expr::column("id")
TableRef variants 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 missing
It's recommended to use the IntoTableRef trait to convert types instead of constructing AST manually.
use sea_orm::sea_query::IntoTableRef;
from_tbl: "foo".into_table_ref(),
dyn <Trait> with impl <Trait> https://github.com/SeaQL/sea-query/pull/982
This gained us up to 10% performance, however it does mean dyn QueryBuilder is no longer possible.Changed Into* traits (like IntoCondition) to be defined as trait IntoCondition: Into<Condition> and implemented for all T: Into<Condition>.
Now IntoCondition and Into<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 as impl From<..> for Condition.
Full list of changed traits:
IntoColumnDef https://github.com/SeaQL/sea-query/pull/975IntoColumnRef https://github.com/SeaQL/sea-query/pull/959IntoCondition https://github.com/SeaQL/sea-query/pull/939IntoIden https://github.com/SeaQL/sea-query/pull/973IntoIndexColumn https://github.com/SeaQL/sea-query/pull/976IntoLikeExpr https://github.com/SeaQL/sea-query/pull/974IntoTableRef https://github.com/SeaQL/sea-query/pull/958IntoTypeRef https://github.com/SeaQL/sea-query/pull/969IntoValueTuple https://github.com/SeaQL/sea-query/pull/960Unboxed Value variants may cause compile error. Simply remove the Box in 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 SqliteExpr and PgExpr for T where T: ExprTrait https://github.com/SeaQL/sea-query/pull/914
Now 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) with ColumnSpec::Check(Check) to support named check constraints https://github.com/SeaQL/sea-query/pull/920
SelectStatement::cross_join no longer accepts a condition https://github.com/SeaQL/sea-query/pull/956
Turned TypeRef from an enum into a struct that reuses TableName. https://github.com/SeaQL/sea-query/pull/969
Changed Expr::TypeName(DynIden) to Expr::TypeName(TypeRef), which can be
qualified.
If you manually construct this variant and it no longer compiles, just add
.into().
Renamed QueryBuilder::prepare_simple_expr to prepare_expr https://github.com/SeaQL/sea-query/pull/988
Changed signature of Expr::Custom https://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 &str to String:
let sql = self.sql.trim().to_owned();
SelectStatement::cross_join https://github.com/SeaQL/sea-query/pull/956sea-query-binder has been superseded with sea-query-sqlxNothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Added JSON binary column type ColumnDef::json_binary()
ColumnDef::json_binary()ColumnDef::custom()Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Publish to crate.io
Publish to crate.io
Your coding agent can read these notes before it upgrades. Set up the MCP server →