【问题标题】:psycopg2.ProgrammingError on Enum type in Flask (database) database migrationFlask(数据库)数据库迁移中枚举类型的 psycopg2.ProgrammingError
【发布时间】:2018-03-07 07:54:39
【问题描述】:

在我的 Flask 应用程序的 postgres 数据库上运行迁移时,我在 Enum 类型上收到以下 psycopg2 错误:

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

我尝试删除 alembic_version 表和迁移文件夹并重新运行 flask db init/migrate/upgrade,但没有成功。

我不得不完全删除数据库来解决问题。

有没有办法在类型已经存在时不重新创建它们?

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)

【问题讨论】:

    标签: postgresql flask flask-sqlalchemy psycopg2


    【解决方案1】:

    您可以使用feedback = db.Column(db.Enum(["NONE", "HIDDENIMAGE"])) 替换您的代码。

    【讨论】:

    • 如果我想在多个表中使用这个 Enum 怎么办?
    • 您可以定义一个列表,其中包含构造枚举类型的值。然后解压到你想定义枚举类型字段的地方。
    【解决方案2】:

    编辑:以下内容不适用于 Alembic。同样的问题在这里:https://github.com/sqlalchemy/alembic/issues/566

    创建列时使用sqlalchemy.dialects.postgresql.ENUM 而不是db.Enum。

    ENUM有可选参数create_type,应该设置为False。

    像这样:

    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)
    

    【讨论】:

      【解决方案3】:

      答案可能已经很晚了,但仍会尝试将其发布给将来寻找此问题的其他人。 (和我一样)

      还有一个create_type kwarg 代表postgresql.ENUM。用于设置 alembic 迁移脚本中枚举类型列的架构。

      这是我的新列定义的样子。 (使用现有的枚举)

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

      这将使用现有枚举作为新列,而不创建新列。

      我在需求文件中使用了SQLAlchemy==1.1.1 和alembic==0.8.8。

      【讨论】:

        猜你喜欢
        • 2020-03-05
        • 2020-01-14
        • 1970-01-01
        • 2013-07-31
        • 2018-03-07
        • 1970-01-01
        • 2015-05-23
        • 1970-01-01
        相关资源
        最近更新 更多