sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateObject)错误解决方法

sqlalchemy.exc.ProgrammingError: psycopg2.errors.DuplicateObject错误解决方法

  • 错误原因
  • 解决方法

错误原因

from sqlalchemy.dialects.postgresql.named_types import ENUM
import enum
db = SQLAlchemy()
class Action(enum.Enum):
    active = 0
    inactive = 1
class BaseModel(db.Model):
    __abstract__ = True
    create_id = db.Column(db.Integer, default=1, comment="创建人")
    create_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")
    update_id = db.Column(db.Integer, default=1, comment="更新人")
    update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    active = db.Column(ENUM(Action, create_type=True), server_default='active')
# 当执行数据迁移后,由于数据出问题,删除了所有migrate产生的文件,及删除对应数据库表
# 二再一次执行数据迁移时,flask --app manage db migrate没有报错,
# 但是flask --app manage db upgrade一直报错。
# 提示错误为
#     sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateObject) 错误:  类型 "action" 已经存在 
#     [SQL: CREATE TYPE action AS ENUM ('active', 'inactive')];
# 猜想是删除数据表不完全

解决方法

  • 方法1:

使用Navicat打开Postgersql数据库找到对应库,执行如下

# 只要删除自定义的枚举类型即可
drop type if exists action;  # 删除枚举类型
> OK
> 时间: 0.004s
> 

# Postgersql 有关枚举sql命令
select * from pg_type WHERE typname='action'; # 类型查询
select * from pg_enum;  # 查询枚举选项
oid     enumtypid  enumsortorder  enumlabel
23890	23889	   1	          active
23892	23889	   2	          inactive
23914	23913	   1	          active
23916	23913	   2	          inactive
CREATE TYPE action AS ENUM ('active', 'inactive'); # 创建枚举
  • 方法2:

修改迁移文件,在ENUM()中添加create_type=False

from sqlalchemy.dialects.postgresql import ENUM
class BaseModel(db.Model):
    __abstract__ = True
    # 默认字段 default,nullable, primary_key, unique, autoincrement, name, onupdate
    create_id = db.Column(db.Integer, default=1, comment="创建人")
    create_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")
    update_id = db.Column(db.Integer, default=1, comment="更新人")
    update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    active = db.Column(ENUM(Action, create_type=False), server_default='active')
# 定义模型枚举字段时,添加create_type=False,但是在迁移文件中还是没有create_type=False属性。如下
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('auth_dept',
    ....
    sa.Column('active', postgresql.ENUM('active', 'inactive', name='action'), server_default='active', nullable=True)
	...)
# 所以解决大方法是在ENUM()中添加create_type=False即可

你可能感兴趣的:(Flask,sqlalchemy,数据库)