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

文章讲述了在使用sqlalchemy进行数据库迁移时遇到psycopg2.errors.DuplicateObject错误,即枚举类型已经存在的问题。解决方案包括通过Navicat手动删除数据库中的枚举类型或者修改迁移文件,将ENUM中的create_type设置为False。还提到了Alembic迁移工具在处理此问题时的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值