2

When running a migration on my Flask app's postgres database I get the following psycopg2 error on an Enum type:

INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> 8753d3c9dbd1, empty message
Traceback (most recent call last):
  File "/home/jul/.miniconda3/envs/audiolabeling/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context
    context)
  File "/home/jul/.miniconda3/envs/audiolabeling/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 470, in do_execute
    cursor.execute(statement, parameters)
psycopg2.ProgrammingError: type "feedbacktype" already exists

I tried to delete the alembic_version table and the migrations folder and rerun flask db init/migrate/upgrade, with no success.

I had to drop the database entirely to solve the issue.

Is there any way to not recreate types when they already exist ?

models.py

from audiolabeling import db
import enum


class FeedBackType(enum.Enum):
    NONE = "none"
    HIDDENIMAGE = "hiddenImage"

class Task(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    feedback = db.Column(db.Enum(FeedBackType))

    def __repr__(self):
        return '<id {}>'.format(self.id)

3 Answers 3

2

Probably pretty late for an answer but will still try to post it for someone else looking for this in the future. (As I was)

There's also a create_type kwarg for postgresql.ENUM. which is used to set the schema for an enum type column in the alembic migration script.

Here's what my new column definition looks like. (Which uses existing an existing enum)


sa.Column('ActionType', postgresql.ENUM('Primary', 'Secondary', name='actiontype', create_type=False), nullable=True),

This will now use the existing enum for the new column without creating a new one.

I'm using SQLAlchemy==1.1.1 and alembic==0.8.8 in my requirements file.

Sign up to request clarification or add additional context in comments.

Comments

0

You can use feedback = db.Column(db.Enum(["NONE", "HIDDENIMAGE"])) to replace your code.

2 Comments

What if I want to use this Enum in several tables ?
You can define a list which consist of the values to construct the enum type. And unpack it in where you want to define a enum type field.
0

EDIT: The below does NOT work with Alembic. Same issue is here: https://github.com/sqlalchemy/alembic/issues/566

Use sqlalchemy.dialects.postgresql.ENUM instead of db.Enum when creating the column.

ENUM has the optional parameter create_type, which should be set to False.

Like so:

from sqlalchemy.dialects.postgresql import ENUM

...

class Task(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    feedback = db.Column(ENUM(FeedBackType, create_type=False))

def __repr__(self):
    return '<id {}>'.format(self.id)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.