Ошибка PostgreSQL: связь уже существует

Я пытаюсь создать таблицу, которая была ранее сброшена.

но когда я делаю CREATE TABLE A ... Я получаю ниже ошибки:

отношение " а " уже существует.

Я проверил делаешь SELECT * FROM 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)
);

7 ответов


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


здесь не должно быть одинарных кавычек 'A'. Одинарные кавычки для строковых литералов: 'some value'.
Либо используйте двойные кавычки, чтобы сохранить правописание верхнего регистра "A":

CREATE TABLE "A" ...

или вообще не используйте кавычки:

CREATE TABLE A ...

, что соответствует

CREATE TABLE a ...

потому что все без кавычек коды are автоматически складывается в нижний регистр в PostgreSQL.


вы могли избегайте проблем с именем индекса полностью, используя более простой синтаксис:

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

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


нельзя создать таблицу с именем, идентичным существующей таблице или представлению в кластере. Чтобы изменить существующую таблицу, используйте ALTER TABLE (ссылка), или удалить все данные в таблице и создать пустую таблицу с нужной схемой, вопрос 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 таблица, если есть


в моем случае это было не до тех пор, пока я не приостановил пакетный файл и немного прокрутил его, это была не единственная ошибка, которую я получил. Мой стало DROP и поэтому таблица не падала в первую очередь (таким образом, отношение действительно все еще существовало). The  я узнал, что называется меткой порядка байтов (BOM). Открыв это в Notepad++, повторно сохраните файл SQL с кодировкой 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

еще одна причина, по которой вы можете получить ошибки, такие как" отношение уже существует", если не правильно выполнить.

одна из причин этого может произойти, если есть другие сеансы, подключенные к базе данных, которые необходимо закрыть в первую очередь.