Создайте ссылку на внешний ключ PostgreSQL со значением по умолчанию NULL

Рассмотрим следующее определение таблицы:

CREATE TABLE containers (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    parent_id SERIAL REFERENCES containers(id)
);

Когда я INSERT INTO containers(name) VALUES('test_name'), я получаю следующее:

SELECT * FROM containers;
 id |   name    | parent_id
----+-----------+-----------
  1 | test_name |         1
(1 row)

Похоже, что значения по умолчанию для parent_id — это значение id той же строки. В идеале это было бы NULL. Я пытался добиться этого с помощью следующего:

CREATE TABLE containers (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    parent_id SERIAL REFERENCES containers(id) DEFAULT NULL
);

Но получил следующую ошибку:

ОШИБКА: для столбца «parent_id» таблицы «контейнеры» указано несколько значений по умолчанию.

Могу ли я что-нибудь сделать, чтобы добиться того, чего хочу?

Используйте INT в качестве типа данных для родительского_ид, а не серийного номера.

Frank Heikens 23.06.2024 16:26

Прочтите Сериал и станет понятно в чем проблема.

Adrian Klaver 23.06.2024 16:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
68
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Типичным вариантом использования здесь будет вставка новой дочерней записи с априорным знанием того, что является родителем дочернего элемента. Итак, предполагая, что ваша первоначальная запись уже была вставлена, мы можем ожидать, что вставка будет выглядеть следующим образом:

INSERT INTO containers (name, parent_id) VALUES('sweet child of parent', 1);

В вашем случае, если намерение состоит в том, чтобы вставить корневой родительский элемент (определяемый как одна запись, не имеющая родительского элемента), вам следует явно указать NULL в качестве parent_id:

INSERT INTO containers (name, parent_id) VALUES('root', NULL);

Я понимаю, просто значение по умолчанию не имеет смысла. По крайней мере, можно ли явно потребовать значение для parent_id (удалить значение по умолчанию)?

galah92 23.06.2024 10:11

... наоборот, это имеет смысл, поскольку автоматически сгенерированное значение id равно 1, и вы не переопределили какое-то другое явное значение parent_id.

Tim Biegeleisen 23.06.2024 10:15

Это не решает реальную проблему с типом данных. serial здесь неправильный тип данных, вам нужно целое число.

Frank Heikens 23.06.2024 20:53
Ответ принят как подходящий

Чтобы гарантировать, что столбец parent_id по умолчанию имеет значение NULL вместо значения идентификатора той же строки, вам необходимо настроить определение таблицы.

Проблема возникает потому, что тип SERIAL автоматически создает последовательность и устанавливает значение по умолчанию, которое противоречит указанию DEFAULT NULL.

Это правильный ответ. Не используйте serial здесь.

Laurenz Albe 24.06.2024 08:03

Другие вопросы по теме