adwhit / diesel-derive-enum Goto Github PK
View Code? Open in Web Editor NEWUse enums with Diesel ORM
License: Apache License 2.0
Use enums with Diesel ORM
License: Apache License 2.0
I've downloaded a backup of the Mysql database from http://www.isfdb.org/ for a hobby project. The database have enums that looks like this:
enum('ANTHOLOGY','BACKCOVERART','CHAPBOOK','COLLECTION','COVERART','INTERIORART','EDITOR','ESSAY','INTERVIEW','NOVEL','NONFICTION','OMNIBUS','POEM','REVIEW','SERIAL','SHORTFICTION')
It would be nice if I could name my rust enum variants BackCoverArt
instead of Backcoverart
without changing anything in the database itself.
Therefore I propose a new DbValueStyle
:
DbValueStyle | Variant | Value |
---|---|---|
SCREAMINGCONCAT | BazQuxx | "BAZQUXX" |
Great crate by the way!
(I made a PR for this: #71)
Using:
diesel = { version = "1.4.3", features = ["network-address", "postgres", "r2d2", "uuidv07", "chrono", "network-address", "serde_json"] }
diesel-derive-enum = { version = "0.4.4", features = ["postgres"] }
I'm having an issue in generating the schema with the proper mappings with the following code:
Postgresql
CREATE TYPE my_enum AS enum ('apple', 'banana', 'cactus');
Rust
#[derive(DbEnum)]
pub enum MyEnum {
Apple,
Banana,
Cactus,
}
diesel print-schema returns the following.
table! {
random_table (id) {
id -> Uuid,
kind -> My_enum,
}
}
I've attempted to use #[DieselType = "My_enum"] but that doesn't seem to make a difference.
New to diesel, so perhaps this is an error by me, and the examples could be clarified to safeguard from me's.
schema.rs: (via diesel print-schema + diesel-derive modifications)
#[derive(PgEnum, Debug, PartialEq)]
#[DieselType = "Foo_status"]
#[warn(non_camel_case_types)]
pub enum FooStatus {
Active,
Inactive,
}
table! {
use diesel::sql_types::{Int4};
use super::Foo_status;
foo (foo_id) {
foo_id -> Int4,
status -> Foo_status,
}
}
Sample app:
#[derive(Queryable)]
pub struct Foo {
pub foo_id: i32,
pub status: FooStatus,
}
let results = foo
.filter(status.eq(FooStatus::Active))
.limit(5)
.load::<Foo>(&connection)
.expect("Error loading posts");
Error:
24 | .load::<Foo>(&connection)
| ^^^^ the trait `diesel::query_builder::QueryId` is not implemented for `diesel_demo::schema::Foo`
And if I add QueryId to FooStatus I get:
1 | #[derive(PgEnum, Debug, PartialEq, QueryId)]
| ^^^^^^^
|
= help: message: #[derive(QueryId)] cannot be used with enums
Hey, I just tried out this crate.
Initial setup works fine, but I'm getting this error when inserting:
diesel::insert_into(db_schema::contacts::table).values(&contact).execute(&*db);
error[E0277]: the trait bound `db::types::Gender: diesel::serialize::ToSql<diesel::sql_types::Nullable<db::types::pg_enum_impl_Gender::GenderMapping>, diesel::pg::Pg>` is not satisfied
--> src/app/users/mod.rs:55:78
|
55 | diesel::insert_into(db_schema::contacts::table).values(&contact).execute(&*db);
| ^^^^^^^ the trait `diesel::serialize::ToSql<diesel::sql_types::Nullable<db::types::pg_enum_impl_Gender::GenderMapping>, diesel::pg::Pg>` is not implemented for `db::types::Gender`
|
Relevant types:
#[derive(Serialize, Deserialize, Identifiable, Queryable, Insertable, Clone, Debug)]
#[table_name = "contacts"]
pub struct Contact{
pub id: Uuid,
pub gender: Option<Gender>,
pub given_name: Option<String>,
pub family_name: Option<String>,
pub company_name: Option<String>,
pub title: Option<String>,
pub phone_landline: Option<String>,
pub phone_mobile: Option<String>,
pub email: Option<String>,
pub birthday: Option<NaiveDate>,
pub address_id: Option<Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(PgEnum, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
pub enum Gender {
Male,
Female,
Other,
}
#[derive(Serialize, Deserialize, Identifiable, Queryable, Insertable, Clone, Debug)]
#[table_name = "contacts"]
pub struct Contact{
pub id: Uuid,
pub gender: Option<Gender>,
pub given_name: Option<String>,
pub family_name: Option<String>,
pub company_name: Option<String>,
pub title: Option<String>,
pub phone_landline: Option<String>,
pub phone_mobile: Option<String>,
pub email: Option<String>,
pub birthday: Option<NaiveDate>,
pub address_id: Option<Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
table! {
use diesel::pg::types::sql_types::*;
use diesel::sql_types::*;
use db::types::GenderMapping;
contacts (id) {
id -> Uuid,
gender -> Nullable<GenderMapping>,
given_name -> Nullable<Text>,
family_name -> Nullable<Text>,
company_name -> Nullable<Text>,
title -> Nullable<Text>,
phone_landline -> Nullable<Text>,
phone_mobile -> Nullable<Text>,
email -> Nullable<Text>,
birthday -> Nullable<Date>,
address_id -> Nullable<Uuid>,
created_at -> Timestamptz,
updated_at -> Timestamptz,
}
}
diesel: 1.1
diesel-derive-enum: 0.3.0
Hi. Isn't the table!
macro should be auto generated by the diesel? And if so then how to "inject" custom enum
s there. Right now I am getting the error from the schema.rs
saying:
cannot find type
Lang_enum
in this scope
Please help!
Thanks in advance
Lots of warning being thrown in test-suite due to diesel-rs/diesel#1785
Update to latest diesel once patch has landed
I'm trying to run an insert_into
, one of the columns being a tuple that corresponds to an enum for which DbEnum
and Eq
are implemented.
Diesel complains that it can't create table::some_enum.eq
expressions, because .eq
does not exist on some_enum
.
Here is the complete error:
error[E0599]: no method named `eq` found for type `schema::item_matching_keys::columns::type_` in the current scope
--> /src/items/import.rs:76:33
|
76 | item_matching_keys::type_.eq(mk.type_),
| ^^
|
::: /src/schema.rs:45:1
|
45 | / table! {
46 | | use diesel::sql_types::*;
47 | | use crate::schema_additions::MatchingKeyType;
48 | | item_matching_keys (id) {
... |
54 | | }
55 | | }
| |_- method `eq` not found for this
|
= note: the method `eq` exists but the following trait bounds were not satisfied:
`&mut schema::item_matching_keys::columns::type_ : diesel::ExpressionMethods`
`&mut schema::item_matching_keys::columns::type_ : std::iter::Iterator`
`&schema::item_matching_keys::columns::type_ : diesel::ExpressionMethods`
`schema::item_matching_keys::columns::type_ : diesel::ExpressionMethods`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following traits define an item `eq`, perhaps you need to implement one of them:
candidate #1: `std::cmp::PartialEq`
candidate #2: `std::iter::Iterator`
candidate #3: `diesel::ExpressionMethods`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
It seems the generated column would need to implement Expression
.
How can I insert my enum in database using tuples ?
Also, if I try to insert it using a struct, by having a structure that contains one such tuple derive Insertable
, it complains when trying to derive that trait :
error[E0277]: the trait bound `schema_additions::MatchingKeyType: diesel::Expression` is not satisfied
--> /src/items/matching_keys.rs:7:38
|
7 | #[derive(Debug, PartialEq, Eq, Hash, Insertable)]
| ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `schema_additions::MatchingKeyType`
|
= note: required because of the requirements on the impl of `diesel::Expression` for `&'insert schema_additions::MatchingKeyType`
= note: required because of the requirements on the impl of `diesel::expression::AsExpression<schema_additions::MatchingKeyType>` for `&'insert schema_additions::MatchingKeyType`
I can't insert my enum in database. Please help !
Something weird happened today. After a clean build, my diesel-derive-enum generated EpisodeMapping suddenly stopped working and I can't figure out why.
table! {
use diesel::sql_types::*;
use crate::db::enums::episode::*;
/// Representation of the `heroes` table.
///
/// (Automatically generated by Diesel.)
heroes (id) {
/// The `id` column of the `heroes` table.
///
/// Its SQL type is `Int4`.
///
/// (Automatically generated by Diesel.)
id -> Int4,
/// The `name` column of the `heroes` table.
///
/// Its SQL type is `Varchar`.
///
/// (Automatically generated by Diesel.)
name -> Varchar,
/// The `appears_in` column of the `heroes` table.
///
/// Its SQL type is `Array<EpisodeMapping>`.
///
/// (Automatically generated by Diesel.)
appears_in -> Array<EpisodeMapping>,
/// The `home_planet` column of the `heroes` table.
///
/// Its SQL type is `Varchar`.
///
/// (Automatically generated by Diesel.)
home_planet -> Varchar,
}
}
error[E0412]: cannot find type `EpisodeMapping` in this scope
--> src/db/schema.rs:335:29
|
335 | appears_in -> Array<EpisodeMapping>,
| ^^^^^^^^^^^^^^ not found in this scope
|
= note: possible candidate is found in another module, you can import it into scope:
crate::db::enums::episode::db_enum_impl_Episode::EpisodeMapping
error: aborting due to previous error
#[derive(Debug, PartialEq, DbEnum, Clone, GraphQLEnum)]
#[PgType = "episode_enum"]
pub enum Episode {
NewHope,
Empire,
Jedi,
}
For some reason the compiler is finding crate::db::enums::episode::db_enum_impl_Episode::EpisodeMapping
but not crate::db::enums::episode::EpisodeMapping
. I'm not sure what happened, I don't think I touched those modules at all, I just did a clean build. Any idea why this is happening?
According to the getting started page on Diesel's docs the schema.rs
file is typically automatically created/updated by diesel setup
or diesel migration run
.
The problem is that the schema.rs
that it generates does not include the proper Mapping
suffix for enum types. This results in errors similar to this.
I am able to work around this issue by adding a patch_file
to diesel.toml, but I would prefer to avoid this.
The ability to use Integer instead of Text for the SQL representation of enums when using the sqlite backend would be useful. It wouldn't be as statically type safe without the check clause, but it would be more efficient than using strings.
The following code:
#[derive(Debug, diesel_derive_enum::DbEnum, diesel::SqlType)]
pub enum A {}
will lead to compiler warning:
warning: unreachable expression
--> src/lib.rs:1:17
|
1 | #[derive(Debug, diesel_derive_enum::DbEnum, diesel::SqlType)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| unreachable expression
| any code following this expression is unreachable
Particularly, if expand the macro issue is clearly seen at ToSql<AMapping, DB>
:
impl<DB: Backend> ToSql<AMapping, DB> for A {
fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
match *self {}
Ok(IsNull::No) // <- that one is unreachable
}
}
I added your crate and did the config in: air-balloon/api@b5ec7ce
Summary of the problems:
account_status -> Enum,
that does not workthe trait diesel::Expression is not implemented for enums::AccountStatus
errorsIf I apply this diff (to un-hack my compiling version)
diff --git a/src/models/user.rs b/src/models/user.rs
index d6df1ab..7621b41 100644
--- a/src/models/user.rs
+++ b/src/models/user.rs
@@ -13,7 +13,7 @@ pub struct User {
pub username: String,
pub first_name: String,
pub last_name: String,
- pub account_status: String,
+ pub account_status: AccountStatus,
pub timezone: Option<String>,
pub first_log_in_at: Option<NaiveDateTime>,
pub last_log_in_at: Option<NaiveDateTime>,
@@ -29,7 +29,7 @@ pub struct NewUser<'a> {
pub username: &'a String,
pub first_name: &'a String,
pub last_name: &'a String,
- pub account_status: &'a String,
+ pub account_status: &'a AccountStatus,
pub timezone: Option<&'a String>,
pub first_log_in_at: Option<&'a NaiveDateTime>,
pub last_log_in_at: Option<&'a NaiveDateTime>,
diff --git a/src/schema.rs b/src/schema.rs
index d727291..25ccfb8 100644
--- a/src/schema.rs
+++ b/src/schema.rs
@@ -9,7 +9,7 @@ table! {
username -> Varchar,
first_name -> Varchar,
last_name -> Varchar,
- account_status -> Varchar,
+ account_status -> AccountStatus,
timezone -> Nullable<Varchar>,
first_log_in_at -> Nullable<Timestamp>,
last_log_in_at -> Nullable<Timestamp>,
I get the following errors
Compiling api v0.1.0 (/mnt/Dev/@air-balloon/api)
error[E0277]: the trait bound `enums::AccountStatus: diesel::Expression` is not satisfied
--> src/models/user.rs:23:10
|
23 | #[derive(Insertable)]
| ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `enums::AccountStatus`
|
= note: required because of the requirements on the impl of `diesel::Expression` for `&'a enums::AccountStatus`
= note: required because of the requirements on the impl of `AsExpression<enums::AccountStatus>` for `&'a enums::AccountStatus`
= note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `enums::AccountStatus: diesel::Expression` is not satisfied
--> src/models/user.rs:23:10
|
23 | #[derive(Insertable)]
| ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `enums::AccountStatus`
|
= note: required because of the requirements on the impl of `diesel::Expression` for `&enums::AccountStatus`
= note: required because of the requirements on the impl of `AsExpression<enums::AccountStatus>` for `&enums::AccountStatus`
= note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `enums::AccountStatus: diesel::Expression` is not satisfied
--> src/models/user.rs:23:10
|
23 | #[derive(Insertable)]
| ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `enums::AccountStatus`
|
= note: required because of the requirements on the impl of `diesel::Expression` for `&'a enums::AccountStatus`
= note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `enums::AccountStatus: diesel::Expression` is not satisfied
--> src/models/user.rs:23:10
|
23 | #[derive(Insertable)]
| ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `enums::AccountStatus`
|
= note: required because of the requirements on the impl of `diesel::Expression` for `&enums::AccountStatus`
= note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.
error: could not compile `api`
To learn more, run the command again with --verbose.
Thank you in advance for helping me, I am new to Rust and am stuck on this error.
I checked in your tests folder but did not find something that helped, that said I applied all valid examples into mine.
It seems that single word names like 'Flow' messes things up. I've created SQL type as:
CREATE TYPE flow AS ENUM ('credit_only', 'debit_only', 'debit_credit');
And corresponding enum as:
#[derive(Debug, PartialEq, DbEnum)]
pub enum Flow {
CreditOnly,
DebitOnly,
DebitCredit
}
Build failed with AsExpression
trait was not satisfied. But after I renamed it to 'account_flow' and added #[DieselType = "Account_flow"]
to the enum, everything compiled just fine. Maybe not the best idea to name types like that, but error messages where quite confusing.
I'm trying to use the enum as an input into a sql_function
, but the compiler complains:
error[E0277]: the trait bound `models::RoomUsage: diesel::Expression` is not satisfied
--> src/db_helpers.rs:55:23
|
55 | let returned_rooms = get_available_rooms(start_date, end_date, room_usage);
| ^^^^^^^^^^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `models::RoomUsage`
|
= note: required because of the requirements on the impl of `diesel::expression::AsExpression<models::RoomUsage>` for `models::RoomUsage`
But a quick glance into the source code shows that you do implement AsExpression
, so I'm wondering what I'm missing here.
Cheers
Hi,
I'm trying to use the following code:
sistemas_de_equipamento.inner_join(avaria)
.filter(AvariaId.eq(avaria_id))
.first(&*conn)
with:
#[derive(Serialize, Queryable, Deserialize)]
pub struct AvariaJson {
pub id: i32,
pub tag: String,
pub descricao: String,
pub flag: f64,
pub taxa: f64,
pub valor: f64,
pub id_sistema: Option<i32>
}
#[derive(Serialize, Queryable, Deserialize)]
pub struct SistemaJson {
pub id: i32,
pub codigo_sistema: String,
pub fxml: String,
pub grupo: TipoGrupo,
pub nome: String
}
#[derive(DbEnum, Serialize, Deserialize)]
#[derive(Debug)]
pub enum TipoGrupo {
PROPULSAO, AUXILIAR, ELETRICA
}
And i'm getting
|
26 | .first(&*conn)
| ^^^^^ the trait `diesel::sql_types::HasSqlType<schema::enum_schemas::TipoGrupo>` is not implemented for `diesel::pg::Pg`
|
= help: the following implementations were found:
<diesel::pg::Pg as diesel::sql_types::HasSqlType<schema::enum_schemas::db_enum_impl_TipoModelo::TipoModeloMapping>>
<diesel::pg::Pg as diesel::sql_types::HasSqlType<schema::enum_schemas::db_enum_impl_TipoInterface::TipoInterfaceMapping>>
<diesel::pg::Pg as diesel::sql_types::HasSqlType<schema::enum_schemas::db_enum_impl_TipoGrupo::TipoGrupoMapping>>
<diesel::pg::Pg as diesel::sql_types::HasSqlType<diesel::sql_types::Inet>>
and 29 others
= note: required because of the requirements on the impl of `diesel::sql_types::HasSqlType<(diesel::sql_types::Integer, diesel::sql_types::Text, diesel::sql_types::Text, schema::enum_schemas::TipoGrupo, diesel::sql_types::Text)>` for `diesel::pg::Pg`
= note: required because of the requirements on the impl of `diesel::sql_types::HasSqlType<((diesel::sql_types::Integer, diesel::sql_types::Text, diesel::sql_types::Text, schema::enum_schemas::TipoGrupo, diesel::sql_types::Text), (diesel::sql_types::Integer, diesel::sql_types::Text, diesel::sql_types::Text, diesel::sql_types::Double, diesel::sql_types::Double, diesel::sql_types::Double, diesel::sql_types::Nullable<diesel::sql_types::Integer>))>` for `diesel::pg::Pg`
= note: required because of the requirements on the impl of `diesel::query_dsl::LoadQuery<diesel::PgConnection, _>` for `diesel::query_builder::SelectStatement<diesel::query_source::joins::JoinOn<diesel::query_source::joins::Join<schema::noctus_schemas::sistemas_de_equipamento::table, schema::noctus_schemas::avaria::table, diesel::query_source::joins::Inner>, diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<schema::noctus_schemas::avaria::columns::id_sistema>, diesel::expression::nullable::Nullable<schema::noctus_schemas::sistemas_de_equipamento::columns::id>>>, diesel::query_builder::select_clause::DefaultSelectClause, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::WhereClause<diesel::expression::operators::Eq<schema::noctus_schemas::avaria::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>>, diesel::query_builder::order_clause::NoOrderClause, diesel::query_builder::limit_clause::LimitClause<diesel::expression::bound::Bound<diesel::sql_types::BigInt, i64>>>`
I've seen issue #12 , but even on 0.4.2 the error persists.
I'm relatively new to diesel, so I might be doing something wrong.
Using a remote DB @khorolets and I discovered that our requests are too slow (observed high latencies). Digging into it we learned that doing an insert of N records in a single query produce N pre-flight queries and they are related to the lookup:
Lines 273 to 277 in 731b86f
Logging out the looked up type we observe:
PgTypeMetadata { oid: 0, array_oid: 0 }
Thus, replacing the lookup call with the const value we avoid all the unrelated requests and our implementation seems to work just fine. It is hard to tell if this is reasonable to use this const instead of a dynamic lookup:
impl HasSqlType<#diesel_mapping> for Pg {
fn metadata(lookup: &Self::MetadataLookup) -> Self::TypeMetadata {
Self::TypeMetadata { oid: 0, array_oid: 0 }
}
}
UPD: Our CREATE TYPE
SQL migration had mismatching names with the enums in the source code, but even once we fixed the mismatch and started observing proper values (PgTypeMetadata { oid: 21564, array_oid: 21563 }
), it did not change anything (still slow if we do this lookup every time). I wonder what is the use of these oid
and array_oid
values since SELECT (with and without filters), UPDATE, and INSERT operations succeed even if the metadata method always returns Self::TypeMetadata { oid: 0, array_oid: 0 }
.
At the moment all the names rely on "sensible conventions". It would be nice to specify renaming etc as custom attributes on the enum, a la serde
Now that master is supporting 2.0-rc0 it'd be nice if a version targeting 2.0 could be released on crates.io, rather than needing a git ref. https://github.com/quodlibetor/diesel-derive-newtype is doing that, for example.
Does it work with sqlite too? As described here: diesel-rs/diesel#343 (comment)
Hi I am using derive enum as follow:
diesel = { version = "1.4.8", features = ["postgres", "r2d2", "chrono", "serde_json"] }
diesel-derive-enum = "1.1.2"
my definition of TransactionStatus
use diesel_derive_enum::DbEnum;
#[derive(Debug, Clone, PartialEq, Eq, DbEnum)]
#[DbValueStyle = "PascalCase"]
#[PgType = "TransactionStatus"]
#[DieselType = "TransactionStatusMapping"]
pub enum TransactionStatus {
Sucess,
Failure,
}
And I got 2 errors:
error[E0277]: the trait bound `Pg: HasSqlType<TransactionStatusMapping>` is not satisfied
--> src/pg_db/models/transaction.rs:111:10
|
111 | .get_results(db_conn)
| ^^^^^^^^^^^ the trait `HasSqlType<TransactionStatusMapping>` is not implemented for `Pg`
|
error[E0277]: the trait bound `transaction_status::TransactionStatus: Queryable<TransactionStatusMapping, Pg>` is not satisfied
--> src/pg_db/models/transaction.rs:107:10
|
107 | .get_results(db_conn)
| ^^^^^^^^^^^ the trait `Queryable<TransactionStatusMapping, Pg>` is not implemented for `transaction_status::TransactionStatus`
|
So I wanted to understand details and run cargo extend
This is output:
pub mod transaction_status {
use diesel_derive_enum::DbEnum;
#[DbValueStyle = "PascalCase"]
#[PgType = "TransactionStatus"]
#[DieselType = "TransactionStatusMapping"]
pub enum TransactionStatus {
Sucess,
Failure,
}
#[automatically_derived]
impl ::core::fmt::Debug for TransactionStatus {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
TransactionStatus::Sucess => {
::core::fmt::Formatter::write_str(f, "Sucess")
}
TransactionStatus::Failure => {
::core::fmt::Formatter::write_str(f, "Failure")
}
}
}
}
#[automatically_derived]
impl ::core::clone::Clone for TransactionStatus {
#[inline]
fn clone(&self) -> TransactionStatus {
match self {
TransactionStatus::Sucess => TransactionStatus::Sucess,
TransactionStatus::Failure => TransactionStatus::Failure,
}
}
}
impl ::core::marker::StructuralPartialEq for TransactionStatus {}
#[automatically_derived]
impl ::core::cmp::PartialEq for TransactionStatus {
#[inline]
fn eq(&self, other: &TransactionStatus) -> bool {
let __self_tag = ::core::intrinsics::discriminant_value(self);
let __arg1_tag = ::core::intrinsics::discriminant_value(other);
__self_tag == __arg1_tag
}
}
impl ::core::marker::StructuralEq for TransactionStatus {}
#[automatically_derived]
impl ::core::cmp::Eq for TransactionStatus {
#[inline]
#[doc(hidden)]
#[no_coverage]
fn assert_receiver_is_total_eq(&self) -> () {}
}
pub use self::db_enum_impl_TransactionStatus::TransactionStatusMapping;
#[allow(non_snake_case)]
mod db_enum_impl_TransactionStatus {
use super::*;
use diesel::Queryable;
use diesel::backend::Backend;
use diesel::expression::AsExpression;
use diesel::expression::bound::Bound;
use diesel::row::Row;
use diesel::sql_types::*;
use diesel::serialize::{self, ToSql, IsNull, Output};
use diesel::deserialize::{self, FromSql, FromSqlRow};
use diesel::query_builder::QueryId;
use std::io::Write;
pub struct TransactionStatusMapping;
#[automatically_derived]
impl ::core::clone::Clone for TransactionStatusMapping {
#[inline]
fn clone(&self) -> TransactionStatusMapping {
TransactionStatusMapping
}
}
impl QueryId for TransactionStatusMapping {
type QueryId = TransactionStatusMapping;
const HAS_STATIC_QUERY_ID: bool = true;
}
impl NotNull for TransactionStatusMapping {}
impl SingleValue for TransactionStatusMapping {}
impl AsExpression<TransactionStatusMapping> for TransactionStatus {
type Expression = Bound<TransactionStatusMapping, Self>;
fn as_expression(self) -> Self::Expression {
Bound::new(self)
}
}
impl AsExpression<Nullable<TransactionStatusMapping>> for TransactionStatus {
type Expression = Bound<Nullable<TransactionStatusMapping>, Self>;
fn as_expression(self) -> Self::Expression {
Bound::new(self)
}
}
impl<'a> AsExpression<TransactionStatusMapping> for &'a TransactionStatus {
type Expression = Bound<TransactionStatusMapping, Self>;
fn as_expression(self) -> Self::Expression {
Bound::new(self)
}
}
impl<'a> AsExpression<Nullable<TransactionStatusMapping>>
for &'a TransactionStatus {
type Expression = Bound<Nullable<TransactionStatusMapping>, Self>;
fn as_expression(self) -> Self::Expression {
Bound::new(self)
}
}
impl<'a, 'b> AsExpression<TransactionStatusMapping>
for &'a &'b TransactionStatus {
type Expression = Bound<TransactionStatusMapping, Self>;
fn as_expression(self) -> Self::Expression {
Bound::new(self)
}
}
impl<'a, 'b> AsExpression<Nullable<TransactionStatusMapping>>
for &'a &'b TransactionStatus {
type Expression = Bound<Nullable<TransactionStatusMapping>, Self>;
fn as_expression(self) -> Self::Expression {
Bound::new(self)
}
}
impl<DB: Backend> ToSql<TransactionStatusMapping, DB> for TransactionStatus {
fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
match *self {
TransactionStatus::Sucess => out.write_all(b"Sucess")?,
TransactionStatus::Failure => out.write_all(b"Failure")?,
}
Ok(IsNull::No)
}
}
impl<DB> ToSql<Nullable<TransactionStatusMapping>, DB> for TransactionStatus
where
DB: Backend,
Self: ToSql<TransactionStatusMapping, DB>,
{
fn to_sql<W: ::std::io::Write>(
&self,
out: &mut Output<W, DB>,
) -> serialize::Result {
ToSql::<TransactionStatusMapping, DB>::to_sql(self, out)
}
}
}
}
And I do not see implementation of FromSql what can be reason why I got this errors?
I'm attempting to build a project in release mode and am getting a failure due to the followign compiler error, however it only happens in release mode not debug mode
error[E0412]: cannot find type `Liquidation_state_enum` in this scope
--> db/src/schema.rs:11:30
|
1 | / table! {
2 | | use diesel::sql_types::*;
3 | | use crate::models::Liquidation_state_enum;
4 | |
... |
11 | | liquidation_state -> Liquidation_state_enum,
| | ^^^^^^^^^^^^^^^^^^^^^^ help: a struct with a similar name exists: `liquidation_state`
12 | | }
13 | | }
| |_- similarly named struct `liquidation_state` defined here
|
= note: consider importing this struct:
crate::models::Liquidation_state_enum
warning: ignoring -C extra-filename flag due to -o flag
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0412`.
error: could not compile `db`
To learn more, run the command again with --verbose.
use crate::schema::liquidation_state_transitions;
use crate::schema::obligation_accounts;
use crate::schema::user_farm_accounts;
use crate::schema::user_farm_manager_accounts;
use diesel::prelude::*;
use diesel_derive_enum;
#[derive(Queryable, Clone)]
pub struct ObligationAccount {
pub id: i32,
pub pubkey: String,
pub authority: String,
pub liquidated: bool,
}
#[derive(Queryable, Clone)]
pub struct UserFarmAccount {
pub id: i32,
pub pubkey: String,
pub authority: String,
pub farm_manager: String,
pub obligations: Vec<String>,
pub obligation_indexes: Vec<i32>,
}
#[derive(Queryable, Clone)]
pub struct UserFarmManagerAccount {
pub id: i32,
pub pubkey: String,
pub authority: String,
pub farm_key: i32,
}
#[derive(Debug, PartialEq, Clone, diesel_derive_enum::DbEnum)]
#[PgType = "Liquidation_state_enum"]
#[DieselType = "Liquidation_state_enum"]
pub enum LiquidationStateEnum {
Start,
Pull,
Repay,
Remove,
Liquidate,
End,
}
#[derive(Queryable, PartialEq, Clone)]
pub struct LiquidationStateTransistion {
pub id: i32,
pub temp_liquidation_account: String,
pub authority: String,
pub user_farm: String,
pub obligation: String,
pub liquidation_state: LiquidationStateEnum,
}
#[derive(Insertable)]
#[table_name = "obligation_accounts"]
pub struct NewObligationAccount<'a> {
pub pubkey: &'a str,
pub authority: &'a str,
pub liquidated: bool,
}
#[derive(Insertable)]
#[table_name = "user_farm_manager_accounts"]
pub struct NewUserFarmManagerAccount<'a> {
pub pubkey: &'a str,
pub authority: &'a str,
pub farm_key: i32,
}
#[derive(Insertable)]
#[table_name = "user_farm_accounts"]
pub struct NewUserFarmAccount<'a> {
pub pubkey: &'a str,
pub authority: &'a str,
pub farm_manager: &'a str,
pub obligations: Option<Vec<String>>,
pub obligation_indexes: Option<Vec<i32>>,
}
#[derive(Insertable)]
#[table_name = "liquidation_state_transitions"]
pub struct NewLiquidationStateTransition<'a> {
pub temp_liquidation_account: &'a str,
pub authority: &'a str,
pub user_farm: &'a str,
pub obligation: &'a str,
pub liquidation_state: LiquidationStateEnum,
}
table! {
use diesel::sql_types::*;
use crate::models::Liquidation_state_enum;
liquidation_state_transitions (id) {
id -> Int4,
temp_liquidation_account -> Varchar,
authority -> Varchar,
user_farm -> Varchar,
obligation -> Varchar,
liquidation_state -> Liquidation_state_enum,
}
}
table! {
use diesel::sql_types::*;
use crate::models::Liquidation_state_enum;
obligation_accounts (id) {
id -> Int4,
pubkey -> Varchar,
authority -> Varchar,
liquidated -> Bool,
}
}
table! {
use diesel::sql_types::*;
use crate::models::Liquidation_state_enum;
user_farm_accounts (id) {
id -> Int4,
pubkey -> Varchar,
authority -> Varchar,
farm_manager -> Varchar,
obligations -> Array<Text>,
obligation_indexes -> Array<Int4>,
}
}
table! {
use diesel::sql_types::*;
use crate::models::Liquidation_state_enum;
user_farm_manager_accounts (id) {
id -> Int4,
pubkey -> Varchar,
authority -> Varchar,
farm_key -> Int4,
}
}
allow_tables_to_appear_in_same_query!(
liquidation_state_transitions,
obligation_accounts,
user_farm_accounts,
user_farm_manager_accounts,
);
# For documentation on how to configure this file,
# see diesel.rs/guides/configuring-diesel-cli
[print_schema]
file = "src/schema.rs"
import_types = ["diesel::sql_types::*", "crate::models::Liquidation_state_enum"]
-- Your SQL goes here
CREATE TABLE obligation_accounts (
id SERIAL PRIMARY KEY NOT NULL,
pubkey VARCHAR NOT NULL UNIQUE,
-- the account field is owner but we're using authority here for consistency
authority VARCHAR NOT NULL,
liquidated BOOLEAN NOT NULL DEFAULT 'f'
);
CREATE TABLE user_farm_accounts (
id SERIAL PRIMARY KEY NOT NULL,
pubkey VARCHAR NOT NULL UNIQUE,
authority VARCHAR NOT NULL,
farm_manager VARCHAR NOT NULL,
obligations TEXT[] NOT NULL DEFAULT '{}',
obligation_indexes INTEGER[] NOT NULL DEFAULT '{}'
);
CREATE TABLE user_farm_manager_accounts (
id SERIAL PRIMARY KEY NOT NULL,
pubkey VARCHAR NOT NULL UNIQUE,
authority VARCHAR NOT NULL,
farm_key INTEGER NOT NULL DEFAULT 0
);
-- liquidation state transition enum
-- it marks the most recent phase in liquidation
-- allowing one to resume from that step
-- the one exception is "end" which indicates liquidation as finished
CREATE TYPE liquidation_state_enum AS ENUM ('start', 'pull', 'repay', 'remove', 'liquidate', 'end');
CREATE TABLE liquidation_state_transitions (
id SERIAL PRIMARY KEY NOT NULL,
temp_liquidation_account VARCHAR NOT NULL UNIQUE,
authority VARCHAR NOT NULL,
user_farm VARCHAR NOT NULL,
obligation VARCHAR NOT NULL,
liquidation_state liquidation_state_enum NOT NULL
);
diesel = { version = "1.4.7", features = ["postgres"] }
diesel-derive-enum = { version = "1.1.1", features = ["postgres"] }
rustc 1.51.0 (2fd73fabe 2021-03-23)
Incorrect syntax near 'ENUM'. Expecting TABLE.
CREATE TYPE gender_types AS ENUM ('Male','Female','Unisex
create TABLE profiles (
uuid UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
date_of_birth TIMESTAMP NOT NULL,
avatar VARCHAR NOT NULL,
genter gender_types NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
SELECT diesel_manage_updated_at('profiles');
[dependencies]
......................
diesel = { version = "1.4.2", features = ["postgres", "r2d2", "uuid", "chrono", "uuidv07"] }
diesel-derive-enum = { version = "0.4", features = ["postgres"] }
.....................
inside my main.rs
pub mod schema;
pub mod db_connection;
pub mod models;
pub mod handlers;
#[macro_use]
extern crate diesel;
extern crate diesel_derive_enum;
extern crate dotenv;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate actix;
extern crate actix_web;
extern crate futures;
use actix_web::{App, HttpServer, web};
use db_connection::establish_connection;```
I think compiletest can be used to check e.g. that the derive will fail if the enum is not fieldless
The current master branch is not compatible with Diesel's master branch (a few minor changes to apply so that it is).
I've pushed a commit to make it compatible on this fork.
I'd like to create a pull request but this is probably not suitable for your master branch because that would break on the current crates.io version of diesel, so it would be better to use a separate branch.
Can you create a new branch (diesel-master-compatible
or similar) so I can open the PR ?
Hi,
After I updated the nightly compiler version I started getting the following error:
|
126 | #[derive(DbEnum, Serialize, Deserialize, Debug, PartialEq, Clone)]
| ^^^^^^ Use of undeclared type or module `TipoInterface`
Looking into the generated code, indeed there was a missing use super::* so the enum name was visible inside the generated code. That fix seems simple enough, so I will open a pull request, if that's alright.
Is it possible to not have a enum type in the database corresponding to the rust enum as it would be easier to just store the value as a string since it will make migrations easier. That way we wont need to mapping also right? Just serialization and deserialization will suffice.
Hey there
I try to use the derive enum macro with diesel master (2.0.0-rc.0) but when trying to define an enum, the compiler complains about an unresolved import:
use diesel::prelude::*;
use diesel_derive_enum::*;
#[derive(Debug, PartialEq, DbEnum)]
#[DieselType = "LanguageEnum"]
#[PgType = "language"]
pub enum Language {
De,
Fr,
It,
En,
}
When trying to use this enum above, the compiler returns:
246 | #[derive(Debug, PartialEq, DbEnum)]
| ^^^^^^
| |
| unresolved import
| help: a similar path exists: `crate::database::schema`
Could someone point me into the right direction?
Does diesel-derive enum support binding an array of enums (i.e. Array, where SampleType is an enum derived by this crate) into a sql_query? I'm seeing the following compiler error with the following code.
let sample_array: Vec<SampleArray> = vec![SampleArray::One];
sql_query(include_str!("queries/test.sql"))
.bind::<DieselUuid, _>(&sample_uuid)
.bind::<DieselUuid, _>(&test_uuid)
.bind::<Array<SampleType>, _>(&sample_array)
.get_results(&cx.dbcon)?
^^^^^^^^^^^ the trait `diesel::query_dsl::LoadQuery<_, _>` is not implemented for `diesel::query_builder::sql_query::UncheckedBind<diesel::query_builder::sql_query::UncheckedBind<diesel::query_builder::sql_query::UncheckedBind<diesel::query_builder::SqlQuery, &uuid::Uuid, diesel::sql_types::Uuid>, &uuid::Uuid, diesel::sql_types::Uuid>, &std::vec::Vec<models::sql_types::SampleType>, diesel::sql_types::Array<models::sql_types::SampleType>>
to avoid things like #12
Hello,
Quick disclaimer, i'm fairly new to rust :).
I've been toying around with this library for hours now, and i simply can't get it to work.
I created the following enum. (Postgres)
CREATE TYPE category_enum AS ENUM ('none', 'pug', 'scrim', 'official');
Created my enum in my models.rs
#[derive(DbEnum)]
pub enum CategoryEnum {
None,
Pug,
Scrim,
Official
}
#[derive(Insertable, Debug)]
#[table_name="delta_stats"]
pub struct NewDeltaStat {
pub value: f64,
pub category: CategoryEnum
}
And applied it to my schema
table! {
use diesel::sql_types::*;
use super::CategoryEnumMapping;
delta_stats (id) {
id -> Int8,
value -> Float8,
category -> CategoryEnumMapping,
}
}
But i get the following error when i try to compile it
error[E0432]: unresolved import `super::CategoryEnumMapping`
--> src/schema.rs:3:9
|
3 | use super::CategoryEnumMapping;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `CategoryEnumMapping` in `schema`
What am i doing wrong here? feel like i have following the documentation from top to toe
I've got the following Cargo.toml
:
[package]
...
[dependencies]
diesel_crate = { version = "1", optional = true, package = "diesel" }
diesel-derive-enum = { version = "0.4", features = ["sqlite"], optional = true }
[features]
diesel = ["diesel_crate", "diesel-derive-enum"]
A feature
can't have the same name as a dependency
, so I rename the diesel
crate to diesel_crate
. In the library, I then use use diesel_crate::prelude::*
for example.
This works, but this library can't handle that situation, because it doesn't explicitly depend on diesel, and requires you to manually add that dependency, which it then expects to be named diesel
.
Now... when I started typing this, I wanted to propose adding diesel as a dependency, but then I realised that would probably require you to enable all features of diesel for this crate to work in all situations, right? 🤔
So yeah, I guess I'll go ahead and create this issue anyway, but unless there's something that Cargo provides to solve this, there's probably no way for this to work, without requiring anyone depending on this crate to automatically include all features of Diesel...
Using this crate with an sqlite database.
This works great:
#[derive(Insertable, Queryable, Identifiable, Debug, PartialEq)]
#[table_name = "evacuateobjects"]
pub struct EvacuateObjectDB {
pub id: String,
pub status: EvacuateObjectStatus,
}
#[derive(DbEnum, Debug, PartialEq, Clone)]
pub enum EvacuateObjectStatus {
Unprocessed,
Processing,
Skipped,
Failed,
Retrying,
}
But this:
#[derive(Insertable, Queryable, Identifiable, Debug, PartialEq)]
#[table_name = "evacuateobjects"]
pub struct EvacuateObjectDB {
pub id: String,
pub status: EvacuateObjectStatus,
}
#[derive(DbEnum, Debug, PartialEq, Clone)]
pub enum SkippedReason {
Retry,
Persistent,
}
#[derive(DbEnum, Debug, PartialEq, Clone)]
pub enum EvacuateObjectStatus {
Unprocessed,
Processing,
Skipped(SkippedReason),
Failed,
Retrying,
}
Gives the error: "Variants must be fieldless"
Would be nice if something like EvacuateObjectStatus::Skipped(SkippedReason::Retry)
could be mapped to a string skipped:retry
.
Since the release of diesel 2.0.0, I've been anxious to see this lib getting updated.
I've tried master against diesel 2 with a big project I have and everything seems good!
Is there anything between us and a new release?
$ psql --version
psql (PostgreSQL) 10.4
$ PG_TEST_DATABASE_URL=postgres://[email protected] cargo test --features postgres
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running target/debug/deps/tests-61de74e2f6241362
running 5 tests
test nullable::nullable_enum_round_trip ... FAILED
test rename::rename_round_trip ... ok
test nullable::not_nullable_enum_round_trip ... ok
test simple::enum_round_trip ... FAILED
test simple::filter_by_enum ... FAILED
failures:
---- nullable::nullable_enum_round_trip stdout ----
thread 'nullable::nullable_enum_round_trip' panicked at 'called `Result::unwrap()` on an `Err` value: DatabaseError(__Unknown, "column \"my_enum\" is of type my_enum but expression is of type pg_temp_7.my_enum")', libcore/result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
---- simple::enum_round_trip stdout ----
thread 'simple::enum_round_trip' panicked at 'called `Result::unwrap()` on an `Err` value: DatabaseError(__Unknown, "column \"my_enum\" is of type my_enum but expression is of type pg_temp_7.my_enum")', libcore/result.rs:945:5
---- simple::filter_by_enum stdout ----
thread 'simple::filter_by_enum' panicked at 'called `Result::unwrap()` on an `Err` value: DatabaseError(__Unknown, "column \"my_enum\" is of type my_enum but expression is of type pg_temp_7.my_enum")', libcore/result.rs:945:5
failures:
nullable::nullable_enum_round_trip
simple::enum_round_trip
simple::filter_by_enum
test result: FAILED. 2 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out
error: test failed, to rerun pass '--lib'
I think this failure is related to behavior changes in TEMP
in PostgreSQL 10.
when using master with diesel 2.0.0-rc.0,
On every DbEnum invocation, I got:
error[E0433]: failed to resolve: could not find `sql_types` in `schema`
--> src/calendar/get.rs:273:39
|
273 | #[derive(Debug, Clone, PartialEq, DbEnum, Serialize, Deserialize)]
| ^^^^^^ could not find `sql_types` in `schema`
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
infer_schema! will "guess" the name of the mapping type, which won't match up with that generated by the macro. Give an example/explanation of this
Not sure if this is just me not doing things right, or if migrations aren't properly working, or what... but I put this in my up.sql
:
CREATE TYPE unit_type AS ENUM ('weight', 'volume');
CREATE TABLE units (
id SERIAL PRIMARY KEY,
base_id INT REFERENCES units(id) ON DELETE CASCADE,
base_multiplier DECIMAL,
name VARCHAR NOT NULL,
type unit_type NOT NULL
);
and after running the migration, Diesel puts this into the generated schema.rs
:
table! {
units (id) {
id -> Int4,
base_id -> Nullable<Int4>,
base_multiplier -> Nullable<Numeric>,
name -> Varchar,
#[sql_name = "type"]
type_ -> Unit_type,
}
}
Already there's a problem. Based on your README, which says
By default, the Postgres and Diesel internal types are inferred from the name of the Rust enum. Specifically, we assume MyEnum corresponds to my_enum in Postgres and MyEnumMapping in Diesel. (The Diesel type is created by the plugin, the Postgres type must be created in SQL).
I would have expected the unit_type
to become UnitType
, not Unit_type
. Then I thought, maybe I have to define UnitType
myself. So I created this before running:
#[derive(Debug, diesel_derive_enum::DbEnum)]
#[PgType = "unit_type"]
#[DieselType = "Unit_type"]
pub enum UnitType {
Weight,
Volume,
}
Running the migration now, it's still the same as above. If I manually change the type_ -> Unit_type
line to type_ -> crate::database::models::Unit_type
, everything works, but this is a relatively fragile solution, as the schema.rs
file gets overwritten by the migration tool, so I'd have to make that change every time.
It's not the end of the world, but it would be nice if it just worked™.
I have the following simple struct and enum:
#[derive(DbEnum, Debug, PartialEq, Clone)]
pub enum ObjectStatus {
Unprocessed,
Processing,
Skipped,
Failed,
Retrying,
}
#[derive(Insertable, Queryable, Identifiable, Debug, PartialEq)]
#[table_name = "evacuateobjects"]
pub struct Object {
pub id: i32,
pub status: ObjectStatus,
}
If I create the table like so:
conn.execute(
r#"
CREATE TABLE evacuateobjects(
id SERIAL PRIMARY KEY,
status TEXT CHECK(status IN ('Unprocessed', 'Processing', 'Skipped', 'Failed', 'Retrying')) NOT NULL
);
"#,
).unwrap();
Any inserts fail with DatabaseError(__Unknown, "CHECK constraint failed: evacuateobjects")'
If I remove the CHECK constraint (status TEXT NOT NULL
) everything works out just fine.
let items = evacuateobjects::table.load::<Object>(conn).unwrap();
assert_eq!(items[0].status, ObjectStatus::Skipped);
Oddly the sqlite enum round trip test passes just fine on the same system.
The generated structs do not implement neither Clone
(nor Copy
, though it does not seem to be useful), which is an issue when building complex queries. I hit this problem while trying to use this in the on
clause for a left_join
, and though I didn't test, most likely for a inner_join
.
table! {
user (id) {
id -> Uuid,
}
}
table! {
use diesel::sql_types::*;
use super::Server_status;
server (id) {
id -> Uuid,
user_id -> Uuid,
status -> Server_status,
}
}
joinable!(server -> user (user_id));
allow_tables_to_appear_in_same_query!(user, server);
#[derive(DbEnum, Clone)]
#[DieselType = "Server_status"]
enum ServerStatus { Stopped, Starting, Running, Stopping, Stopped }
#[derive(Queryable)]
#[table_name = "user"]
struct User {
id: Uuid,
}
#[derive(Queryable, Associations)]
#[belongs_to(User)]
#[table_name = "server"]
struct Server {
id: Uuid,
user_id: Uuid,
status: ServerStatus,
}
let user_and_server = user
.find(Uuid::new_v4())
.left_join(
server
.on(server::dsl::user_id.eq(user::dsl::id.nullable())
.and(server::dsl::status.eq(ServerStatus::Running))
)
)
.first::<(User, Option<Server>)>(&conn)?;
The above wouldn't compile, complaining that Server_status
does not implement Clone
:
error[E0277]: the trait bound `Instance_status: Clone` is not satisfied
--> src/main.rs:346:13
|
346 | / server
347 | | .on(server::dsl::user_id.eq(user::dsl::id.nullable())
348 | | .and(server::dsl::status.eq(ServerStatus::Running))),
| |_______________________________________________________________________^ expected an implementor of trait `Clone`
|
= note: required because of the requirements on the impl of `Clone` for `diesel::expression::bound::Bound<Server_status, ServerStatus>`
...
(walls of trait bounds)
Adding the following made the code happily compile and run:
impl Clone for Server_status {
fn clone(&self) -> Self { Self }
}
Thanks for the great lib!
Since diesel-rs/diesel@bd13f24
I may open a PR to fix this soon.
It seems for the likes of Postgres Diesel will generate appropriate types for enums, as described in #43. But what about when I am using Sqlite? i.e.
CREATE TABLE PriceMetadata (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
category TEXT CHECK(category IN ('A', 'B', 'C')) NOT NULL,
data TEXT NOT NULL
)
Is there anything I can do other than using patch_file
to replace the Text
in my schema.rs?
I'm sorry if this has been asked somewhere already, but would it be possible for this to be merged into diesel? Instead of living as a separate crate.
I made an example repo to show the issue: benthillerkus/diesel-enum-trouble.
The API has changed quite a bit. No pressing need but would be nice to give it a whirl.
I've come up with a clever design pattern that simplifies the dilemma of making accessible types within schema.rs
Instead of listing all import_types
within diesel.toml as mapping to individual crates, instead make a diesel_types module and then pub use everything that's needed.
An example:
Diesel.toml
# For documentation on how to configure this file,
# see diesel.rs/guides/configuring-diesel-cli
[print_schema]
file = "src/schema.rs"
import_types = ["crate::diesel_types::*"]
diesel_types.rs
pub use crate::data::{gender::Gender as Enum_users_gender, user::UserStatus as Enum_users_status};
pub use diesel::sql_types::*;
pub use diesel_full_text_search::TsVector as Tsvector;
users/gender.rs
use async_graphql::Enum;
use diesel_derive_enum::DbEnum;
use diesel_derives::SqlType;
use serde::{Deserialize, Serialize};
#[Enum]
#[derive(Serialize, Deserialize, DbEnum, SqlType, Debug)]
#[PgType = "enum_users_gender"]
pub enum Gender {
Male,
Female,
Other,
#[serde(rename = "Prefer not to say")]
Undisclosed,
}
The advantage of this design pattern is that it's easier to do aliases and that because you're guaranteed types will be used there won't be any compiler warnings. It's a simple way to import all enums, base types and to address the TsVector alias all in one.
enum:
#[derive(Debug, PartialEq, DbEnum, Clone, Serialize, Deserialize)]
#[PgType = "permission"]
#[DieselType = "Permission"]
pub enum PermissionEnum {
#[serde(rename = "admin")]
#[db_rename = "mod"] // with or without both fails
Admin,
}
struct:
#[derive(Queryable, Serialize, Identifiable)]
#[table_name = "user"]
pub struct User {
pub id: Uuid,
pub permissions: Vec<PermissionEnum>,
}
query:
dsl::user
.find(user_id)
.get_result::<R>(&conn)
error:
the trait `diesel::deserialize::FromSql<model::db_enum_impl_PermissionEnum::Permission, diesel::pg::Pg>` is not implemented for `model::PermissionEnum`
IMO, in addition to the current implement of FromSqlRow
, FromSql
should also be implemented.
I have an enum roughly like this:
#[derive(Clone, Copy, DbEnum, Debug, Deserialize, Diff, PartialEq, Serialize)]
pub enum MyType {
A = 0,
B = 1,
C = 2,
}
Yet when I attempt to use it, I get this:
the trait `diesel::Queryable<diesel::sql_types::Integer, _>` is not implemented for `MyType`
Thanks.
Hi! In my code I think I have an issue with renaming of nullable enum values, so I figured I try running your tests and maybe extending them. However I didn't get that far, because I get test fails with the tests that are already there.
Is this something to do with my setup? I tried both postgres 9 and 10.
martin@rexlk:~/dev/diesel-derive-enum/tests$ cargo test --features postgres nullable
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running target/debug/deps/tests-4a7899a1fb646353
running 2 tests
test nullable::nullable_enum_round_trip ... FAILED
test nullable::not_nullable_enum_round_trip ... ok
failures:
---- nullable::nullable_enum_round_trip stdout ----
thread 'nullable::nullable_enum_round_trip' panicked at 'called `Result::unwrap()` on an `Err` value: DatabaseError(__Unknown, "column \"my_enum\" is of type my_enum but expression is of type pg_temp_2.my_enum")', src/libcore/result.rs:916:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
failures:
nullable::nullable_enum_round_trip
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 3 filtered out
Please fix this library to work with diesel 2.0
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.