Ошибка 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)
);

Ответ 1

Наконец-то я обнаружил ошибку. Проблема в том, что имя ограничения первичного ключа равно имени таблицы. Я не знаю, как postgres представляет ограничения, но я думаю, что ошибка "Отношение уже существует" запускалась во время создания ограничения первичного ключа, потому что таблица уже была объявлена. Но из-за этой ошибки таблица не была создана в конце.

Ответ 2

Здесь не должно быть никаких кавычек '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
);

Выполняет то же самое, что и исходный запрос, только это позволяет избежать конфликтов имен автоматически. Он автоматически выбирает следующий свободный идентификатор. Подробнее о серийном типе в руководстве.

Ответ 3

Вы не можете создать таблицу с именем, которое идентично существующей таблице или представлению в кластере. Чтобы изменить существующую таблицу, используйте ALTER TABLE (link) или удалите все данные, находящиеся в настоящее время в таблице, и создайте пустую таблицу с нужным schema, вопрос DROP TABLE до CREATE TABLE.

Возможно, что создаваемая вами последовательность является виновником. В PostgreSQL последовательности реализуются как таблица с определенным набором столбцов. Если у вас уже определенная последовательность, вам, вероятно, следует пропустить ее. К сожалению, нет эквивалента в CREATE SEQUENCE для конструкции IF NOT EXISTS, доступной в CREATE TABLE. По внешнему виду, вы можете создать свою схему безоговорочно, так или иначе, поэтому разумно использовать

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

до остальной части вашего обновления схемы; Если это не очевидно, Это приведет к удалению всех данных в таблице csd_relationship, если есть

Ответ 4

В моем случае это было только до тех пор, пока я не запустил пакетный файл и немного прокрутился, это была не единственная ошибка, которую я получил. Моя команда DROP стала DROP, и поэтому таблица не упала в первую очередь (таким образом, отношение действительно существовало).  Я узнал, что он называется знаком байтового байта (BOM). Открыв это в Notepad ++, заново сохраните файл SQL с кодировкой, установленной в UTM-8 без спецификации, и она отлично работает.

Ответ 5

В моем случае у меня была последовательность с тем же именем.

Ответ 6

В моем случае я переходил с 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

Ответ 7

Это связано с тем, что таблица A уже существует, когда вы пытаетесь ее создать.

откройте таблицу A и убедитесь, что она не существует.