🎉 Мы рады выпустить SeaORM 0.9.0
сегодня! Вот некоторые основные особенности 🌟:
Обновление зависимостей
[#834] Мы обновили несколько основных зависимостей:
- Обновление
sqlx
до 0.6 - Обновление
time
до 0.3 - Обновление
uuid
до 1.0 - Обновление
sea-query
до 0.26 - Обновление
sea-schema
до 0.9
Обратите внимание, что вам также может потребоваться обновить соответствующую зависимость в вашем приложении.
Предложено
- Роб Гилсон
- boraarslan
Внесено:
- Билли Чан
Пагинация курсора
[#822] Пагинация моделей на основе столбца(ов), например, первичного ключа.
// Create a cursor that order by `cake`.`id`
let mut cursor = cake::Entity::find().cursor_by(cake::Column::Id);
// Filter paginated result by `cake`.`id` > 1 AND `cake`.`id` < 100
cursor.after(1).before(100);
// Get first 10 rows (order by `cake`.`id` ASC)
let rows: Vec<cake::Model> = cursor.first(10).all(db).await?;
// Get last 10 rows (order by `cake`.`id` DESC but rows are returned in ascending order)
let rows: Vec<cake::Model> = cursor.last(10).all(db).await?;
Предложено
- Лукас Берези
Внесено
- Эмиль Фугулин
- Билли Чан
Вставить конфликт
[#791] Вставка активной модели с поведением при конфликте.
let orange = cake::ActiveModel {
id: ActiveValue::set(2),
name: ActiveValue::set("Orange".to_owned()),
};
// On conflict do nothing:
// - INSERT INTO "cake" ("id", "name") VALUES (2, 'Orange') ON CONFLICT ("name") DO NOTHING
cake::Entity::insert(orange.clone())
.on_conflict(
sea_query::OnConflict::column(cake::Column::Name)
.do_nothing()
.to_owned()
)
.exec(db)
.await?;
// On conflict do update:
// - INSERT INTO "cake" ("id", "name") VALUES (2, 'Orange') ON CONFLICT ("name") DO UPDATE SET "name" = "excluded"."name"
cake::Entity::insert(orange)
.on_conflict(
sea_query::OnConflict::column(cake::Column::Name)
.update_column(cake::Column::Name)
.to_owned()
)
.exec(db)
.await?;
Предложено
- baoyachi. Он же: Ржавоволосые крабы
Предоставлено
- liberwang1013
Объединение таблиц с помощью пользовательских условий и псевдонима таблицы
[#793, #852] Щелкните Пользовательские условия присоединения и Пользовательские присоединения, чтобы узнать больше.
assert_eq!(
cake::Entity::find()
.column_as(
Expr::tbl(Alias::new("fruit_alias"), fruit::Column::Name).into_simple_expr(),
"fruit_name"
)
.join_as(
JoinType::LeftJoin,
cake::Relation::Fruit
.def()
.on_condition(|_left, right| {
Expr::tbl(right, fruit::Column::Name)
.like("%tropical%")
.into_condition()
}),
Alias::new("fruit_alias")
)
.build(DbBackend::MySql)
.to_string(),
[
"SELECT `cake`.`id`, `cake`.`name`, `fruit_alias`.`name` AS `fruit_name` FROM `cake`",
"LEFT JOIN `fruit` AS `fruit_alias` ON `cake`.`id` = `fruit_alias`.`cake_id` AND `fruit_alias`.`name` LIKE '%tropical%'",
]
.join(" ")
);
Предложено
- Крис Цанг
- Tuetuopay
- Лоик
Внесено
- Билли Чан
- Мэтт
- liberwang1013
(де)сериализация пользовательского типа JSON
[#794] JSON, хранящийся в базе данных, может быть десериализован в пользовательский struct в Rust.
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "json_struct")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
// JSON column defined in `serde_json::Value`
pub json: Json,
// JSON column defined in custom struct
pub json_value: KeyValue,
pub json_value_opt: Option<KeyValue>,
}
// The custom struct much derive `FromJsonQueryResult`, `Serialize` and `Deserialize`
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, FromJsonQueryResult)]
pub struct KeyValue {
pub id: i32,
pub name: String,
pub price: f32,
pub notes: Option<String>,
}
Предложено
- Мара Шульке
- Крис Цанг
Внесено
- Билли Чан
Производное имя миграции
[#736] Внедрение процедурных макросов DeriveMigrationName
для вывода имени миграции из имени файла.
use sea_orm_migration::prelude::*;
// Used to be...
pub struct Migration;
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20220120_000001_create_post_table"
}
}
// Now... derive `DeriveMigrationName`,
// no longer have to specify the migration name explicitly
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table( ... )
.await
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table( ... )
.await
}
}
Предложено
- Крис Цанг
Внесено
- smonv
- Лукас Поттаст
- Билли Чан
Улучшения интерфейса SeaORM CLI
- [#735] Улучшение протоколирования команды generate entity
- [#588] Генерация перечислений с числовыми вариантами
- [#755] Разрешить применение старых ожидающих миграций
- [#837] Пропускать генерацию сущностей для игнорируемых таблиц
- [#724] Генерировать код для
time
crate - [#850] Добавить различные типы столбцов blob
- [#422] Генерировать файлы сущностей с именем схемы Postgres
- [#851] Пропускать проверку строки соединения на наличие учетных данных
Предложено & Внесено
- ttys3
- kyoto7250
- yb3616
- Эмиль Фугулин
- Бастиан
- Нахуа
- Майк
- Франк Хорват
- Майкель Вевер
Различные усовершенствования
- [#800] Добавлен
sqlx_logging_level
вConnectOptions
. - [#768] Добавлено
num_items_and_pages
вPaginator
- [#849] Добавлено
TryFromU64
дляtime
- [#853] Включите имя столбца в
TryGetError::Null
- [#778] Рефакторинг метрик потоков
Предложено & Внесено:
- SandaruKasa
- Эрик
- Эмиль Фугулин
- Ренато Динхани
- kyoto7250
- Марко Напетти
Примеры интеграции
SeaORM хорошо сочетается с другими крейтами в экосистеме async. Мы поддерживаем множество примеров проектов для создания REST, GraphQL и gRPC сервисов. Хотелось бы больше примеров!
- Пример Rocket
- Пример Actix
- Пример Axum
- Пример Poem
- Пример GraphQL
- Пример jsonrpsee
- Пример Tonic
Спонсор
Наш профиль спонсора на GitHub открыт! Если вы чувствуете щедрость, небольшое пожертвование будет высоко оценено.
Большое спасибо нашим спонсорам 😇:
- Эмиль Фугулин
- Дин Шезер
- Шейн Свеллер
- Сакти Дви Кахионо
- Неназванный спонсор
- Неназванный спонсор
Сообщество
SeaQL — это проект, управляемый сообществом. Мы приглашаем вас принять участие, внести свой вклад и вместе строить будущее Rust.
Вот дорожная карта для SeaORM 0.10.x
.