首页 > 解决方案 > 存在视图时,Postgres 无法删除表

问题描述

我正在使用sqlalchemypsycopg2使用if_exists='replace'. to_sql()这会删除表,然后重新创建它。但是,如果我定义了一个使用该表的视图,则该to_sql()命令将失败,因为 postgres 不会删除该表。除了首先手动删除视图,重新创建它之外,还有其他方法吗?谢谢。

标签: python-3.xpostgresqlsqlalchemy

解决方案


如果您的目标是 DROP 包含相关对象的 TABLE,例如 VIEW,则需要使用 CASCADE 关键字来强制 DROP 相关对象(这是一个递归操作)。

有关详细信息,请参阅 PostgreSQL依赖项跟踪

为了确保整个数据库结构的完整性,PostgreSQL 确保您不能删除其他对象仍然依赖的对象。

默认情况下这是不可行的,实际上在一个表上创建一个 VIEW 是一种方便的方法来防止这个 TABLE 被意外删除。无论如何,您可能还想阅读这篇文章以使用 SQLAlchemy 实现 CASCADE 行为。

然后,在重新创建表后重新创建丢失的相关对象仍然是您的责任。SQLAlchemy 似乎没有相关视图的表示。但是它有一个创建视图的包,并且可以在一定程度上填补这个空白(未经测试)。

因此,它不能单独由 SQLAlchemy 处理。您将需要一个脚本/函数来播放 DDL 语句来重新创建您的依赖项(可能使用上面提到的包)。

如果您可以使用纯 SQL 标准(或使用包)重新创建它,那么您将不会失去 SQLAlchemy ORM 的好处(至少是抽象数据库引擎并可以移植到另一个引擎的能力)。

关于依赖项跟踪,查看应该重新创建哪些相关对象的简单方法是:

BEGIN;
DROP TABLE mytable CASCADE;
ROLLBACK;

您还可以使用 pg_depend非常方便但特定于 PostgreSQL 的功能。


推荐阅读