如何使用SQLAlchemy和PostgreSQL删除自定义类型?

3 投票
2 回答
1477 浏览
提问于 2025-04-18 10:02

我有一个脚本,用来清理数据库,这个脚本在我们的测试中被广泛使用。

最开始,我们尝试使用 SQLAlchemy 的 Metadata.drop_all() 方法,但在删除时没有处理好一些外键,导致出现错误。后来,我找到了 @zzzeek 提供的 这个脚本,它做的事情几乎一样,但更“聪明”。这个脚本能处理所有与外键相关的问题,不过现在出现了几个关于自定义类型(ENUMs)变化的问题。我的问题是,如何用 SQLAlchemy 删除这些自定义类型?难道只能手动执行 DROP TYPE 吗?

数据库中的表是用 Alembic 创建的,虽然上面的脚本成功删除了所有表,但一些自定义的 ENUM 类型仍然存在,导致在尝试重新创建它们时出现问题。

重新创建整个数据库并不是一个理想的解决方案,因为应用程序的默认数据库用户通常没有权限创建数据库。

2 个回答

0

这个问题虽然很老旧,但如果在任何 postgresql.ENUM 定义中设置了 create_type=False,你还是可能会遇到这个问题。

根据 SQLAlchemy 的文档,关于 create_type

当设置为 False 时,不会进行检查,也不会执行 CREATE TYPE 或 DROP TYPE,除非直接调用 ENUM.create() 或 ENUM.drop()。

这意味着在运行测试时,即使有使用 create_all()drop_all() 的设置和清理,这两个操作也不会影响自定义的枚举类型。

解决办法很简单,就是去掉 create_type=False,因为默认值是 True。这样一来,所有自定义类型会在测试开始时创建,并在结束时删除,从而确保测试数据库是干净的。

1

你确定你的元数据实例完整地描述了所有的表吗?

可以试试:

Metadata.reflect()
Metadata.drop_all()

撰写回答