-
-
Notifications
You must be signed in to change notification settings - Fork 520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Casting columns as a different data type on select, insert and update #1304
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine by me
@@ -338,6 +340,42 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr { | |||
fn into_expr(self) -> Expr { | |||
Expr::expr(self.into_simple_expr()) | |||
} | |||
|
|||
/// Cast column expression used in select statement. | |||
/// By default it only cast database enum as text. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I don't understand is, under what circumstance is not default
?
How do I customize the behaviour?
This seems to be part of the public API, and is it intended? Can we hide it instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's intended to be part of the public API. For example, user can override it and cast citext
column type as text
during select, SELECT CAST("citext_column" AS text), ...
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a self-explanatory test case now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added 6295fcf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah okay, the only remaining question now is naming.
For example cast_value_enum
only do any casting only if it is an enum and so I think it will be better named as may_be_cast_value_enum
But then, cast_value
is also a bit confusing. I understand now it's the counterpart to cast_select
, but of course cast_insert_or_update
is too long as a name. So may be we can use the word, save
.
And so, the entire naming could be: select_as
and save_as
, cast_save_as
etc?
I think
|
sounds good! |
Nice! I'll work on that :) |
…SeaQL#1304) * Cast select and value * Refactoring * Test casting Postgres citext * Fixup * Revert * Add test cases * Fixup * Rename methods
@billy1624 Hey this does not seem to work, I tried the sea-orm on master:
Tried inserting: let user_params = UserActiveModel::from_json(user_json)?.set_timestamps();
let user = user_params.insert(&state.database_connection).await?; Entity: //! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.7
use sea_orm::{entity::prelude::*, Set};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "users")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
#[serde(skip_deserializing)] // Skip deserializing
pub id: Uuid,
pub first_name: String,
pub last_name: String,
#[sea_orm(unique)]
pub nickname: String,
pub password: String,
#[sea_orm(
column_type = r#"Custom("citext".into())"#,
save_as = "citext"
select_as = "text",
)]
pub email: String,
pub country: String,
#[serde(skip_deserializing)]
pub created_at: DateTimeUtc,
#[serde(skip_deserializing)]
pub updated_at: DateTimeUtc,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}
impl ActiveModel {
pub fn set_timestamps(mut self) -> Self {
if self.created_at.is_not_set() {
self.created_at = Set(chrono::Utc::now())
}
self.updated_at = Set(chrono::Utc::now());
self
}
} Error
|
Hey @praveenperera, thanks for asking!! Notice the #[sea_orm(
column_type = r#"Custom("citext".into())"#,
save_as = "citext"
- select_as = "citext",
+ select_as = "text",
)]
pub email: String, |
Hey @billy1624, sorry that's what I had before and I was changing stuff to try stuff out. I tried select_as ="text" again and same error. I invited you to the repo to check it out. On the |
Okay. I know what have happened... "a missing #[sea_orm(
column_type = r#"Custom("citext".into())"#,
- save_as = "citext"
+ save_as = "citext",
select_as = "text",
)]
pub email: String, |
Hmm interesting that actually fixed it. Thanks! |
Nice! |
@billy1624 Would this be possible to use when using the Got it, maybe would be a good thing to add to docs? impl ColumnTrait for Column {
type EntityName = Entity;
fn def(&self) -> ColumnDef {
match self {
Self::Id => ColumnType::Uuid.def(),
Self::FirstName => ColumnType::String(Some(255u32)).def(),
Self::LastName => ColumnType::String(Some(255u32)).def(),
Self::Nickname => ColumnType::String(Some(255u32)).def().unique(),
Self::HashedPassword => ColumnType::String(Some(255u32)).def(),
Self::Email => ColumnType::Custom("citext".to_owned()).def().unique(),
Self::Country => ColumnType::String(Some(255u32)).def(),
Self::CreatedAt => ColumnType::TimestampWithTimeZone.def(),
Self::UpdatedAt => ColumnType::TimestampWithTimeZone.def(),
}
}
fn select_as(&self, expr: Expr) -> SimpleExpr {
match self {
Self::Email => SimpleExpr::cast_as(Into::<SimpleExpr>::into(expr), Alias::new("text")),
_ => self.select_enum_as(expr),
}
}
} |
* Update 02-writing-migration.md * Update SeaORM/docs/03-migration/02-writing-migration.md * Support various UUID formats that are available in `uuid::fmt` module (SeaQL/sea-orm#1325) * Casting columns as a different data type on select, insert and update (SeaQL/sea-orm#1304) * Methods of `ActiveModelBehavior` receive db connection as a parameter (SeaQL/sea-orm#1145, SeaQL/sea-orm#1328) * Added `execute_unprepared` method to `DatabaseConnection` and `DatabaseTransaction` (SeaQL/sea-orm#1327) * Added `Select::into_tuple` to select rows as tuples (instead of defining a custom Model) (SeaQL/sea-orm#1311) * Generate `#[serde(skip)]` for hidden columns (SeaQL/sea-orm#1171, SeaQL/sea-orm#1320) * Generate entity with extra derives and attributes for model struct (SeaQL/sea-orm#1124, SeaQL/sea-orm#1321) * Generate entity with extra derives and attributes for model struct (SeaQL/sea-orm#1124, SeaQL/sea-orm#1321) * async_trait * Migrations are now performed inside a transaction for Postgres (SeaQL/sea-orm#1379) * `MockDatabase::append_exec_results()`, `MockDatabase::append_query_results()`, `MockDatabase::append_exec_errors()` and `MockDatabase::append_query_errors()` take any types implemented `IntoIterator` trait (SeaQL/sea-orm#1367) * Cleanup the use of `vec!` macros * Added `DatabaseConnection::close` (SeaQL/sea-orm#1236) * Added `ActiveValue::reset` to convert `Unchanged` into `Set` (SeaQL/sea-orm#1177) * Added `QueryTrait::apply_if` to optionally apply a filter (SeaQL/sea-orm#1415) * Added the `sea-orm-internal` feature flag to expose some SQLx types (SeaQL/sea-orm#1297, SeaQL/sea-orm#1434) * Add `QuerySelect::columns` method - select multiple columns (SeaQL/sea-orm#1264) * Edit * Update SeaORM/docs/02-install-and-config/02-connection.md Co-authored-by: Chris Tsang <chris.2y3@outlook.com> * Update SeaORM/docs/05-basic-crud/03-insert.md Co-authored-by: Chris Tsang <chris.2y3@outlook.com> * fmt * Edit --------- Co-authored-by: Chris Tsang <chris.2y3@outlook.com>
PR Info
citext
seaography#104New Features
ColumnTrait::select_as()
andColumnTrait::select_enum_as()
methods: casting select expression of a columnColumnTrait::save_as()
andColumnTrait::save_enum_as()
methods: casting value of a column in insert and update statementselect_as
andsave_as
macro attribute toDeriveEntityModel