如何使用SQLAlchemy和PostgreSQL删除自定义类型?
我有一个脚本,用来清理数据库,这个脚本在我们的测试中被广泛使用。
最开始,我们尝试使用 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()