Flask sqlalchemy postgresql枚举不会在数据库迁移时创建类型

Flask sqlalchemy postgresql枚举不会在数据库迁移时创建类型,flask,sqlalchemy,flask-sqlalchemy,flask-migrate,sqlalchemy-migrate,Flask,Sqlalchemy,Flask Sqlalchemy,Flask Migrate,Sqlalchemy Migrate,我在Python3下使用Flask开发了一个web应用程序。我在db迁移/升级时遇到postgresql枚举类型问题 我在模型中添加了一列“状态”: class Banner(db.Model): ... status = db.Column(db.Enum('active', 'inactive', 'archive', name='banner_status')) ... python manage.py db migrate生成的迁移是: from alembic

我在Python3下使用Flask开发了一个web应用程序。我在db迁移/升级时遇到postgresql枚举类型问题

我在模型中添加了一列“状态”:

class Banner(db.Model):
    ...
    status = db.Column(db.Enum('active', 'inactive', 'archive', name='banner_status'))
    ...
python manage.py db migrate生成的迁移是:

from alembic import op
import sqlalchemy as sa

def upgrade():
    op.add_column('banner', sa.Column('status', sa.Enum('active', 'inactive', 'archive', name='banner_status'), nullable=True))

def downgrade():
    op.drop_column('banner', 'status')
当我升级python manage.py db时,我得到一个错误:

...
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) type "banner_status" does not exist
LINE 1: ALTER TABLE banner ADD COLUMN status banner_status

 [SQL: 'ALTER TABLE banner ADD COLUMN status banner_status']
为什么迁移不创建类型“banner\u status”?

$ pip freeze
alembic==0.8.6
Flask==0.10.1
Flask-Fixtures==0.3.3
Flask-Login==0.3.2
Flask-Migrate==1.8.0
Flask-Script==2.0.5
Flask-SQLAlchemy==2.1
itsdangerous==0.24
Jinja2==2.8
Mako==1.0.4
MarkupSafe==0.23
psycopg2==2.6.1
python-editor==1.0
requests==2.10.0
SQLAlchemy==1.0.13
Werkzeug==0.11.9
我做错了什么?

$ pip freeze
alembic==0.8.6
Flask==0.10.1
Flask-Fixtures==0.3.3
Flask-Login==0.3.2
Flask-Migrate==1.8.0
Flask-Script==2.0.5
Flask-SQLAlchemy==2.1
itsdangerous==0.24
Jinja2==2.8
Mako==1.0.4
MarkupSafe==0.23
psycopg2==2.6.1
python-editor==1.0
requests==2.10.0
SQLAlchemy==1.0.13
Werkzeug==0.11.9

我用它来解决这个问题

我更改了迁移代码,迁移如下所示:

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

def upgrade():
    banner_status = postgresql.ENUM('active', 'inactive', 'archive', name='banner_status')
    banner_status.create(op.get_bind())

    op.add_column('banner', sa.Column('status', sa.Enum('active', 'inactive', 'archive', name='banner_status'), nullable=True))

def downgrade():
    op.drop_column('banner', 'status')

    banner_status = postgresql.ENUM('active', 'inactive', 'archive', name='banner_status')
    banner_status.drop(op.get_bind())

现在
python manage.py db upgrade\grade
成功执行。

我认为这种方法更简单:

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

def upgrade():
    # others_column = ...
    banner_status = postgresql.ENUM('active', 'inactive', 'archive', name='banner_status', create_type=False), nullable=False)

如果需要,还将
postgresql.ENUM
添加到您的
grade()
函数中。

从reading开始,您可能需要手动创建和删除枚举。对于降级,您还可以通过直接执行SQL(至少对于postgres):
op.execute(“drop-TYPE banner_status;”)来避免重复
@Geekfish为什么不将
postgresql.ENUM('active','inactive','archive',name='banner\u status')
移动到升级和降级方法之外?有什么不好的地方吗?@Jatimir我已经有一段时间没有调查过了,但你的建议可能没问题!实际上,您可以直接将
banner_status
作为列类型传递,而不是通过
sa.Enum(…)
重新定义它。降级时不需要声明所有枚举选项,只需
bind=op.get_bind()
然后
sa.Enum(name='banner_status')。drop(bind,checkfirst=False)