Ошибка 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
еще одна причина, по которой вы можете получить ошибки, такие как" отношение уже существует", если не правильно выполнить.
одна из причин этого может произойти, если есть другие сеансы, подключенные к базе данных, которые необходимо закрыть в первую очередь.