web-dev-qa-db-fra.com

sqlalchemy postgresql enum ne crée pas de type lors de la migration de db

Je développe une application web en utilisant Flask sous Python3. J'ai un problème avec le type d'énumération postgresql sur db migrate/upgrade.

J'ai ajouté une colonne "status" au modèle:

class Banner(db.Model):
    ...
    status = db.Column(db.Enum('active', 'inactive', 'archive', name='banner_status'))
    ...

Migration générée par python manage.py db migrate est:

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')

Et quand je fais python manage.py db upgrade J'obtiens une erreur:

...
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']

Pourquoi la migration ne crée pas un type "banner_status"?

Qu'est-ce que je fais mal?

$ 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
27
Meatbot

J'ai décidé ce problème en utilisant ça.

J'ai changé le code de migration et la migration ressemble à ceci:

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())

Et maintenant python manage.py db upgrade\downgrade est exécuté avec succès.

50
Meatbot

Je pense que cette façon est plus simple:

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)

Vous avez également ajouté le postgresql.ENUM À votre fonction downgrade() si nécessaire.

2
Gofy and Kitty