PostgreSQL 错误:关系已存在
我正在尝试创建一个之前删除的表。
但是当我执行CREATE TABLE A ..
时。我收到以下错误:
关系“A”已存在。
我验证了 SELECT * FROM A
的操作,但随后又出现了另一个错误:
关系“A”不存在。
我已经尝试在列出所有关系的 \dS+
中找到它,但它不在那里。
为了使这个问题变得复杂,我通过在另一个数据库中创建这个表来测试这一点,并且得到了相同的错误。我认为删除该表时可能会出现错误。有什么想法吗?
这是代码:我正在使用 Power SQL 生成的代码。我在不使用序列的情况下遇到了同样的错误。当我更改名称时它才起作用,在这种情况下我不能这样做。
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)
);
I am trying to create a table that was dropped previously.
But when I do the CREATE TABLE A ..
. I am getting below error:
Relation 'A' already exists.
I verified doing SELECT * FROM A
, but then I got another error:
Relation 'A' does not exists.
I already tried to find it in \dS+
listing all relations, and it is not there.
To complicate this, I have tested this by creating this table in another database and I got the same error. I am thinking that could be an error when this table was dropped. Any ideas?
Here is the code: I'm using a generated code from Power SQL. I have the same error without using the sequence. It just works when I change the name and in this case I can not do that.
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)
);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
我终于发现了错误。问题在于主键约束名称与表名称相同。我不知道 postgres 如何表示约束,但我认为在创建主键约束期间会触发错误“关系已存在”,因为表已声明。但由于这个错误,最终没有创建表。
I finally discover the error. The problem is that the primary key constraint name is equal the table name. I don know how postgres represents constraints, but I think the error "Relation already exists" was being triggered during the creation of the primary key constraint because the table was already declared. But because of this error, the table wasnt created at the end.
这里不应有单引号
。单引号用于字符串文字:'A'
'some value'
。要么使用双引号来保留“A”的大写拼写:
要么根本不使用引号:
... 与:... 相同
,因为所有不带引号的标识符都是在 Postgres 中折叠为小写。请参阅:
您可以通过使用更简单的语法完全避免索引名称问题:
与原始查询相同,只是它通过自动选择下一个空闲标识符来避免命名冲突。有关
serial
类型的更多信息,请参阅手册。There should be no single quotes here
. Single quotes are for string literals:'A'
'some value'
.Either use double quotes to preserve the upper case spelling of "A":
Or don't use quotes at all:
... which is identical to:
... because all unquoted identifiers are folded to lower case in Postgres. See:
You can avoid problems with the index name completely by using simpler syntax:
Does the same as your original query, only it avoids naming conflicts by picking the next free identifier automatically. More about the
serial
type in the manual.您不能创建与集群中现有表或视图名称相同的表。要修改现有表,请使用
ALTER TABLE
(链接),或者要删除表中当前的所有数据并创建具有所需架构的空表,请在CREATE TABLE
之前发出DROP TABLE
。罪魁祸首可能是您正在创建的序列。在 PostgreSQL 中,序列被实现为具有一组特定列的表。如果您已经定义了序列,则可能应该跳过创建它。不幸的是,
CREATE SEQUENCE
中没有与CREATE TABLE
中可用的IF NOT EXISTS
结构等效的内容。从表面上看,无论如何,您可能会无条件地创建架构,因此在架构的其余部分更新之前使用是合理的;如果不明显,这将删除
csd_relationship
表中的所有数据(如果有)You cannot create a table with a name that is identical to an existing table or view in the cluster. To modify an existing table, use
ALTER TABLE
(link), or to drop all data currently in the table and create an empty table with the desired schema, issueDROP TABLE
beforeCREATE TABLE
.It could be that the sequence you are creating is the culprit. In PostgreSQL, sequences are implemented as a table with a particular set of columns. If you already have the sequence defined, you should probably skip creating it. Unfortunately, there's no equivalent in
CREATE SEQUENCE
to theIF NOT EXISTS
construct available inCREATE TABLE
. By the looks of it, you might be creating your schema unconditionally, anyways, so it's reasonable to usebefore the rest of your schema update; In case it isn't obvious, This will delete all of the data in the
csd_relationship
table, if there is any您可能会收到“关系已存在”之类的错误的另一个原因是
DROP
命令未正确执行。发生这种情况的原因之一是,如果有其他会话连接到数据库,您需要先关闭这些会话。
Another reason why you might get errors like "relation already exists" is if the
DROP
command did not execute correctly.One reason this can happen is if there are other sessions connected to the database which you need to close first.
就我而言,我有一个同名的序列。
In my case, I had a sequence with the same name.
就我而言,直到我暂停批处理文件并向上滚动一点,这并不是我遇到的唯一错误。我的
DROP
命令已变为DROP
,因此表一开始就没有被删除(因此关系确实仍然存在)。我学到的
称为字节顺序标记 (BOM)。在 Notepad++ 中打开此文件,重新保存 SQL 文件,并将编码设置为 UTM-8 无 BOM,它运行良好。In my case, it wasn't until I PAUSEd the batch file and scrolled up a bit, that wasn't the only error I had gotten. My
DROP
command had becomeDROP
and so the table wasn't dropping in the first place (thus the relation did indeed still exist). The
I've learned is called a Byte Order Mark (BOM). Opening this in Notepad++, re-save the SQL file with Encoding set to UTM-8 without BOM and it runs fine.您可能在运行
CREATE TABLE
之后再运行它。因此,您可能正在第二次创建表,而第一次尝试已经创建了它。You may be running the
CREATE TABLE
after already running it. So you may be creating a table for a second time, while the first attempt already created it.就我而言,我是从 9.5 迁移到 9.6。
所以为了恢复数据库,我正在做:
当然它是在有数据的旧 postgreSQL 数据库上执行的!如果您的新实例位于端口 5433,则正确的方法是:
In my case I was migrating from 9.5 to 9.6.
So to restore a database, I was doing :
Of course it was executing on the old postgreSQL database where there are datas! If your new instance is on port 5433, the correct way is :
有时,当您使用不同的数据库用户创建表并尝试使用不同的用户
SELECT
时,会发生这种错误。您可以使用以下查询授予所有权限。
您还可以授予 DML 语句的访问权限
Sometimes this kind of error happens when you create tables with different database users and try to
SELECT
with a different user.You can grant all privileges using below query.
And also you can grant access for DML statements
问题在于主键约束名称与表名称相同。
我不知道postgres如何表示约束,但我认为错误“Relation
已存在”在创建主键期间被触发
约束,因为该表已经声明。但因为这个错误,
该表最后并未创建。
给出不同的名称来约束
注意 - 转到 SQL 选项卡并检查表名称和约束
享受:)
The problem is that the primary key constraint name is equal the table name.
I don't know how postgres represents constraints, but I think the error “Relation
already exists” was being triggered during the creation of the primary key
constraint because the table was already declared. But because of this error,
the table wasnt created at the end.
give different name to constrain
Note- go to SQL tab and check table name and constrain
Enjoy :)
您已经发现问题的根源是主键与表同名,但让我解释一下为什么这是一个问题。
所有主要约束和唯一约束都是使用唯一索引实现的。在 PostgreSQL 中,该索引必须与约束具有相同的名称。因此,您的命令尝试创建一个名为
csd_relationship
的索引,就像表一样。现在在 PostgreSQL 中,表、索引、序列、视图和复合数据类型都共享相同的名称空间,也就是说,在同一个模式中不能有两个同名的表、索引、序列、视图和复合数据类型。技术原因是所有这些对象的元数据都存储在目录表
pg_class
中,并且pg_class
对(relname, relnamespace)
有唯一的约束code>,即表名和schema的组合。You already found that the root of the problem was that the primary key had the same name as the table, but let me explain why that is a problem.
All primary and unique constraints are implemented using unique indexes. In PostgreSQL, that index must have the same name as the constraint. So your command tries to create an index named
csd_relationship
, just like the table.Now in PostgreSQL, tables, indexes, sequences, views and composite data types all share the same name space, that is, there cannot be two of them with the same name in the same schema. The technical reason is that the metadata of all these objects are stored in the catalog table
pg_class
, andpg_class
has a unique constraint on(relname, relnamespace)
, that is, the combination of table name and schema.运行终端命令“dotnet ef database update”后出现此错误。我的解决方案是打开数据库并删除/删除同名的表。
I got this error after running the terminal command "dotnet ef database update". My solution was to open the database and delete/drop tables with the same name.
我的错误是:
当更改为:
可以
添加
pk_
到前缀my error is :
when change to this:
is ok
add
pk_
to prefix