问题描述
在过去的某个时候,我进行了一次像元迁移,该迁移创建了一个users
表,例如...
def upgrade():
...
op.create_table(
"users",sa.Column("id",sa.Integer(),autoincrement=True,nullable=False),...
sa.Column("type",sa.Enum("Foo","Bar","Baz",name="usertype"),...
)
...
...这将自动创建名为usertype
的枚举,其值为"Foo","Baz"
。
现在,我要创建其他表,该表也引用相同的枚举。例如,
def upgrade():
...
op.create_table('foobar',sa.Column('id',...
sa.Column('user_type',sa.Enum(< ???????? >),...
)
引用现有枚举的语法是什么?
我似乎在文档中找不到答案:https://docs.sqlalchemy.org/en/13/core/type_basics.html#sqlalchemy.types.Enum
解决方法
Ali Kazai 的回答
# This is not the usual sqlalchemy.Enum !
from sqlalchemy.dialects import postgresql
sa.Column('type',postgresql.ENUM('a','b',name='my_enum',create_type=False),nullable=False),
,
我建议不要这样做,因为模型定义和迁移文件之间存在差异。请记住,如果枚举曾经改变过,那么Alembic首先需要检测到枚举已经改变,其次要知道旧值是什么。否则,处理它的唯一可能方法是将列类型更改为VARCHAR
,然后再返回到ENUM
,但这比仅添加或删除一个更昂贵且痛苦的操作。潜在价值。
假设我们有以下枚举:
class Animal(enum.Enum):
DOG = 'DOG'
CAT = 'CAT'
HAMSTER = 'HAMSTER'
对于postgres
,您可以使用sqlalchemy.dialects.postgres.ENUM
并将其传递给现有枚举:
animal = Column(ENUM(Animal),nullable=False)
但是flask-migrate
(使用alembic
)然后写出迁移计划中的值:sa.Column('gender',sa.Enum('DOG','CAT','HAMSTER'))
。出于上述原因这样做。
例如,如果您真的想要这样做,例如因为您知道值永远不会改变,则可以使用sa.Enum(*Animal._member_names_)
,因为Animal._member_names_ = ['DOG','HAMSTER']
。
找不到有关如何修复此错误的太多信息,但您需要执行此操作。
在您自动生成迁移后,只需将 create_type=False 添加到迁移文件中的枚举字段即可。
sa.Column('user_type',sa.Enum(< ???????? >,