V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nonozone
V2EX  ›  Flask

请教一个 flask 枚举数的问题

  •  
  •   nonozone ·
    nonozone · 60 天前 · 1383 次点击
    这是一个创建于 60 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问了半天 ai 也没解决。

    class ApprovalStatus(PyEnum):
        PENDING = 'pending'
        APPROVED = 'approved'
        REJECTED = 'rejected'
    
    
    class Approval(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        content_type = db.Column(db.String(50), nullable=False)
        content_id = db.Column(db.Integer, nullable=False)
        field_name = db.Column(db.String(50), nullable=False)
        new_value = db.Column(db.Text, nullable=False)
        status = db.Column(db.Enum(ApprovalStatus), default=ApprovalStatus.PENDING)
        
    
        submitter_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
        submit_time = db.Column(db.DateTime, default=current_time)
        reviewer_id = db.Column(db.Integer, db.ForeignKey('user.id'))
        review_time = db.Column(db.DateTime, default=current_time)
        review_comment = db.Column(db.Text)
    
        submitter = db.relationship('User', foreign_keys=[submitter_id])
        reviewer = db.relationship('User', foreign_keys=[reviewer_id])
    
        __table_args__ = (db.UniqueConstraint('content_type', 'content_id'),)
    
        @property
        def content(self):
            model = getattr(models, self.content_type)
            return model.query.get(self.content_id)
    

    模型是这样,但是在 flask admin 访问审核这个栏目的时候,总是提示

    LookupError: 'pending' is not among the defined enum values. Enum name: approvalstatus. Possible values: PENDING, APPROVED, REJECTED

    和解哦。

    结果检查,数据库的状态栏的值都是小写的。

    7 条回复    2024-09-11 11:13:26 +08:00
    lovekernel
        1
    lovekernel  
       60 天前
    你是否最近对数据库进行了迁移或修改?
    可以尝试检查数据库迁移工具(如 Flask-Migrate )是否正确处理了枚举类型。
    nonozone
        2
    nonozone  
    OP
       60 天前
    已经有了啊。数据库我也查询了,状态都是小写的:
    ```
    # revision identifiers, used by Alembic.
    revision = '616677b3122c'
    down_revision = 'b96ad24de868'
    branch_labels = None
    depends_on = None


    def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('approval',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('content_type', sa.String(length=50), nullable=False),
    sa.Column('content_id', sa.Integer(), nullable=False),
    sa.Column('submitter_id', sa.Integer(), nullable=False),
    sa.Column('reviewer_id', sa.Integer(), nullable=True),
    sa.Column('status', sa.Enum('pending', 'approved', 'rejected', name='approval_status'), nullable=True),
    sa.Column('submit_time', sa.DateTime(), nullable=True),
    sa.Column('review_time', sa.DateTime(), nullable=True),
    sa.Column('review_comment', sa.Text(), nullable=True),
    sa.ForeignKeyConstraint(['reviewer_id'], ['user.id'], ),
    sa.ForeignKeyConstraint(['submitter_id'], ['user.id'], ),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('content_type', 'content_id')
    )
    with op.batch_alter_table('user', schema=None) as batch_op:
    batch_op.add_column(sa.Column('avatar', sa.String(length=120), nullable=True))

    # ### end Alembic commands ###
    ```
    nevermoreluo
        3
    nevermoreluo  
       60 天前
    是我太久不写 py 了嘛,我不记得有个 PyEnum 的类型,先确认下你自己用的 orm 再确定继承的枚举父类对不对吧。
    nonozone
        4
    nonozone  
    OP
       60 天前
    @nevermoreluo

    from enum import Enum as PyEnum

    不过现在即使改成:

    class ApprovalStatus(enum.Enum):
    PENDING = 'pending'
    APPROVED = 'approved'
    REJECTED = 'rejected'

    也一样。

    总之就是明明数据库里实际的值都是小写,但是好像处理的时候,总体提示说应该大写。

    除非不用这种方法。

    vote_status = db.Column(Enum('open', 'closed', 'auto', name='weekly_vote_status_enum'), default='auto')

    这样写倒是没问题
    zhufpy
        5
    zhufpy  
       60 天前
    PENDING = 'PENDING'
    APPROVED = 'APPROVED'
    REJECTED = 'REJECTED'
    nonozone
        6
    nonozone  
    OP
       58 天前
    @zhufpy 是的,只能左右两边同样的大小写才可以,但是这个枚举数,不是左边我是名称,跟右边的值,不用完全一样么?
    zhufpy
        7
    zhufpy  
       58 天前
    @nonozone 右边的值是存在数据库中的值,左边的则是你代码中使用的值,可以不一样的,左边甚至可以写 A ,B ,C ,但是鉴于见词知意,左右一样最好啦。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2865 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 11:13 · PVG 19:13 · LAX 03:13 · JFK 06:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.