PostgreSQL 错误: 关系已经存在

我尝试创建一个以前删除过的表。

但是当我做 CREATE TABLE A ..的时候,我得到了以下错误:

关系“ A”已经存在。

我验证了 SELECT * FROM A的操作,但随后又出现了另一个错误:

关系 A 不存在。

我已经试图找到它在 \dS+列出所有的关系,它不存在。
为了使问题复杂化,我在另一个数据库中创建了这个表,并且得到了相同的错误。我认为这可能是一个错误,当这个表被删除。有什么想法吗?

下面是代码: 我使用的是从 PowerSQL 生成的代码。我没有使用序列也有同样的错误。它只是工作时,我改变了名称,在这种情况下,我不能这样做。

CREATE SEQUENCE csd_relationship_csd_relationship_id_seq;
CREATE TABLE csd_relationship (
csd_relationship_id INTEGER NOT NULL DEFAULT nextval('csd_relationship_csd_relationship_id_seq'::regclass),
type_id INTEGER NOT NULL,
object_id INTEGER NOT NULL,
CONSTRAINT csd_relationship PRIMARY KEY (csd_relationship_id)
);
212201 次浏览

这里不应该有单引号 'A'。单引号用于字符串文字: 'some value'
要么使用双引号来保留“ A”的大写:

CREATE TABLE "A" ...

或者根本不用引号:

CREATE TABLE A ...

CREATE TABLE a ...

因为所有未引用的 识别资料都是 在 PostgreSQL 中自动折叠成小写


使用更简单的语法可以完全避免索引名称的问题:

CREATE TABLE csd_relationship (
csd_relationship_id serial PRIMARY KEY,
type_id integer NOT NULL,
object_id integer NOT NULL
);

与原始查询相同,只是它通过自动选择下一个空闲标识符来避免命名冲突。更多关于 手册中的 serial类型的信息。

不能创建名称与群集中现有表或视图相同的表。若要修改现有表,请使用 ALTER TABLE(连结),或删除表中当前的所有数据并创建具有所需模式的空表,请在 CREATE TABLE之前发出 DROP TABLE

可能你正在创建的序列就是罪魁祸首。在 PostgreSQL 中,序列实现为包含特定列集的表。如果您已经定义了序列,那么您可能应该跳过创建它。不幸的是,在 CREATE SEQUENCE中没有与 CREATE TABLE中可用的 IF NOT EXISTS构造等价的东西。看起来,您可能无条件地创建模式,所以使用它是合理的

DROP TABLE IF EXISTS csd_relationship;
DROP SEQUENCE IF EXISTS csd_relationship_csd_relationship_id_seq;

在您的模式更新的其余部分之前; 如果不明显,请使用 这将删除 csd_relationship表中的所有数据(如果有的话)

我终于发现了错误。问题是主键约束名称与表名称相等。我不知道 postgres 是如何表示约束的,但是我认为在创建主键约束期间触发了“关系已经存在”错误,因为表已经声明了。但是由于这个错误,最后没有创建表。

在我的例子中,直到我暂停了批处理文件并向上滚动了一点,这不是我得到的唯一错误。我的 DROP命令已经变成了 DROP,因此表从一开始就没有掉下来(因此这个关系确实仍然存在)。我学到的 叫做字节顺序标记(BOM)。在 Notepad + + 中打开此文件,重新保存 SQL 文件,并将 Encoding 设置为 UTM-8而不使用 BOM,这样就可以正常运行。

在我的例子中,我有一个同名的序列。

我的情况是从9.5迁移到9.6。 为了恢复数据库,我做了:

sudo -u postgres psql -d databse -f dump.sql

当然,它是在有数据的旧 postgreSQL 数据库上执行的!如果您的新实例位于端口5433上,正确的方法是:

sudo -u postgres psql -d databse -f dump.sql -p 5433

您可能会得到诸如“关系已经存在”之类的错误的另一个原因是如果 DROP命令没有正确执行。

发生这种情况的一个原因是,如果有其他连接到数据库的会话,您需要首先关闭它们。

当您创建具有不同数据库用户的表并尝试使用不同用户的 SELECT时,有时会发生这种错误。 您可以使用以下查询授予所有权限。

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA schema_name TO username;

还可以授予对 DML 语句的访问权限

GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA schema_name TO username;

您可能在已经运行了 CREATE TABLE之后才运行它。因此,您可能正在第二次创建表,而第一次尝试已经创建了表。

  • 问题是主键约束名称与表名称相等。

  • 我不知道 postgres 如何表示约束,但我认为错误“关系 “已经存在”在创建主键时被触发 约束,因为表已经声明。但是由于这个错误, 表格不是在最后创建的。

  • 给约束赋予不同的名称

    注意-转到 SQL 选项卡并检查表名和约束

享受:)