请教一个 flask 枚举数的问题

73 天前
 nonozone

问了半天 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

和解哦。

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

1432 次点击
所在节点    Flask
7 条回复
lovekernel
73 天前
你是否最近对数据库进行了迁移或修改?
可以尝试检查数据库迁移工具(如 Flask-Migrate )是否正确处理了枚举类型。
nonozone
73 天前
已经有了啊。数据库我也查询了,状态都是小写的:
```
# 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
73 天前
是我太久不写 py 了嘛,我不记得有个 PyEnum 的类型,先确认下你自己用的 orm 再确定继承的枚举父类对不对吧。
nonozone
73 天前
@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
73 天前
PENDING = 'PENDING'
APPROVED = 'APPROVED'
REJECTED = 'REJECTED'
nonozone
71 天前
@zhufpy 是的,只能左右两边同样的大小写才可以,但是这个枚举数,不是左边我是名称,跟右边的值,不用完全一样么?
zhufpy
71 天前
@nonozone 右边的值是存在数据库中的值,左边的则是你代码中使用的值,可以不一样的,左边甚至可以写 A ,B ,C ,但是鉴于见词知意,左右一样最好啦。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1071149

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX