使用 SeaORM 将枚举实现为 PostgreSQL 列

问题描述 投票:0回答:1

我目前困惑于如何使我的其中一列成为不同支付类型(现金、信用卡、借记卡等)的枚举

这就是我目前的表,其中 manager 是对 SchemaManager 的引用

       manager
            .create_table(
                Table::create()
                    .table(Orders::Table)
                    .if_not_exists()
                    (Creating a couple other columns)...
    // This line    .col(ColumnDef::new(Orders::PaymentType).enumeration(**PaymentOptions**, PaymentOptions::**iter()**).not_null())
                    (Just creating some more columns)...
                    .to_owned()
            )
            .await?;

在一个单独的文件中,我有这样的枚举 PaymentOptions:

use strum_macros::EnumIter;

#[derive(Debug, EnumIter)]
pub enum PaymentOptions {
    Cash,
    Credit, 
    Debit, 
    Voucher,
}

我收到 2 个编译器错误(在每个粗体部分下),第一个(在 PaymentOptions 下)是:

expected value, found enum PaymentOptionsrustcClick for full compiler diagnostic
mod.rs(6, 1): the enum is defined here
m20220101_000001_create_table.rs(24, 74): you might have meant to use one of the following enum variants: 
m20220101_000001_create_table::PaymentOptions::Cash, 
m20220101_000001_create_table::PaymentOptions::Credit, 
m20220101_000001_create_table::PaymentOptions::Debit, 
m20220101_000001_create_table::PaymentOptions::Voucher

第二个是:

no variant or associated item named `iter` found for enum `PaymentOptions` in the current scope
items from traits can only be used if the trait is in scoperustcClick for full compiler diagnostic

mod.rs(6, 1): variant or associated item `iter` not found for this enum

m20220101_000001_create_table.rs(1, 1): trait `IntoEnumIterator` which provides `iter` is implemented but 
not in scope; perhaps you want to import it: `use strum::IntoEnumIterator;`

我研究了 active_enum 和 ActiveEnumValue,但我对它背后的文档了解不够,无法确定我是否可以真正使用它们作为解决方案或如何实现它们。

也许我还可以继续使用.enumeration:

**Documentation Excerpt**
pub fn enumeration<N, S, V>(&mut self, name: N, variants: V) -> &mut ColumnDef
where
    N: IntoIden,
    S: IntoIden,
    V: IntoIterator<Item = S>,
Set column type as enum.

但不清楚它真正想要什么作为参数传递给我。

postgresql rust sea-orm
1个回答
0
投票

经过一段时间的研究,我发现有几种方法可以做到这一点,你真的只需要尝试每一种方法,因为其中一些方法有时会因为没有真正明显的原因而不起作用,而且它还取决于你的数据库正在使用(mySQL,PostgreSQL等),但这应该解释其中的大部分内容:https://www.sea-ql.org/SeaORM/docs/next/generate-entity/enumeration/

我发现最简单的方法(使用 PostgreSQL),就是像这样创建枚举:

#[derive(DeriveIden)]
#[sea_orm(enum_name = "payment_options")]
pub enum PaymentOptions {
    #[sea_orm(iden = "payment_options")]
    Enum,
    #[sea_orm(iden = "cash")]
    Cash,
    #[sea_orm(iden = "credit")]
    Credit, 
    #[sea_orm(iden = "debit")]
    Debit, 
    #[sea_orm(iden = "voucher")]
    Voucher,
} 

最重要的部分是确保包含 enum_name 和 DeriveIden。

然后您可以继续将其创建为新类型,如下所示:

        manager
            .create_type(
                Type::create()
                    .as_enum(PaymentOptions::Enum)
                    .values(
                        [
                            PaymentOptions::Cash, 
                            PaymentOptions::Credit, 
                            PaymentOptions::Debit, 
                            PaymentOptions::Voucher
                        ]
                    )
                    .to_owned(),
            )
            .await?;

还有其他方法来创建新类型,但我认为这是最直接、最可靠的方法。

然后我只需要在创建表时实现它,如下所示:

.col(ColumnDef::new(Orders::PaymentType).custom(PaymentOptions::Enum).not_null())

对于遇到同样问题的其他人,我建议您从我附加的链接中彻底阅读文档,因为其他方法可能更适合您

© www.soinside.com 2019 - 2024. All rights reserved.