Ошибка 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 и убедитесь, что она не существует.