- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这是我的 Post 模型:
class Post(Base):
__tablename__ = 'posts'
title = db.Column(db.String(120), nullable=False)
description = db.Column(db.String(2048), nullable=False)
我想给它添加 Enum status
。所以,我创建了一个新的枚举:
import enum
class PostStatus(enum.Enum):
DRAFT='draft'
APPROVE='approve'
PUBLISHED='published'
并为模型添加了一个新字段:
class Post(Base):
...
status = db.Column(db.Enum(PostStatus), nullable=False, default=PostStatus.DRAFT.value, server_default=PostStatus.DRAFT.value)
完成FLASK_APP=server.py flask db migrate
后,生成了这样的迁移:
def upgrade():
op.add_column('posts', sa.Column('status', sa.Enum('DRAFT', 'APPROVE', 'PUBLISHED', name='poststatus'), server_default='draft', nullable=False))
尝试升级数据库后,我得到:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) type "poststatus" does not exist
LINE 1: ALTER TABLE posts ADD COLUMN status poststatus DEFAULT 'draf...
^
[SQL: "ALTER TABLE posts ADD COLUMN status poststatus DEFAULT 'draft' NOT NULL"]
poststatus
没有在数据库级自动创建?在类似的迁移中。server_default
选项?我需要 ORM 级默认值和 DB 级默认值,因为我正在更改现有行,因此不应用 ORM 默认值。draft
等?我认为应该有 ENUM 值,而不是名称。提前谢谢你。
最佳答案
Why real values in DB are 'DRAFT', 'APPROVE', 'PUBLISHED', but not draft, etc? I supposed there should be ENUM values, not names.
正如 Peter Bašista 已经提到的,SQLAlchemy 在数据库中使用枚举名称(DRAFT、APPROVE、PUBLISHED)。我认为这样做是因为枚举值(“草稿”、“批准”、...)在 Python 中可以是任意类型,并且不能保证它们是唯一的(除非使用 @unique
) .
然而,自从 SQLAlchemy 1.2.3 以来,Enum
类接受一个参数 values_callable
,它可用于存储枚举值 在数据库中:
status = db.Column(
db.Enum(PostStatus, values_callable=lambda obj: [e.value for e in obj]),
nullable=False,
default=PostStatus.DRAFT.value,
server_default=PostStatus.DRAFT.value
)
Why type poststatus was not created on DB-level automatically? In the similar migration it was.
我认为基本上您遇到了 alembic 的限制:在某些情况下它无法正确处理 PostgreSQL 上的枚举。我怀疑您案例中的主要问题是 Autogenerate doesn't correctly handle postgresql enums #278 .
我注意到如果我使用 alembic.op.create_table
类型创建正确所以我的解决方法基本上是:
enum_type = SQLEnum(PostStatus, values_callable=lambda enum: [e.value for e in enum])
op.create_table(
'_dummy',
sa.Column('id', Integer, primary_key=True),
sa.Column('status', enum_type)
)
op.drop_table('_dummy')
c_status = Column('status', enum_type, nullable=False)
add_column('posts', c_status)
关于python - 如何将枚举与 SQLAlchemy 和 Alembic 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47206201/
我是一名优秀的程序员,十分优秀!