Задать вопрос
@AndreyRafalsky132

Зачем нужен DEFERRABLE INITIALLY DEFERRED в результате sqlmigrate для миграции добавления модели?

Подскажите пожалуйста, зачем используется DEFERRABLE INITIALLY DEFERRED при создании таблицы модели? Вот такой результат я получил:

BEGIN;
--
-- Create model Post
--
CREATE TABLE "blog_post" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(250) NOT NULL, "slug" varchar(250) NOT NULL, "b
ody" text NOT NULL, "publish" datetime NOT NULL, "created" datetime NOT NULL, "updated" datetime NOT NULL, "status" varchar(10) NOT NULL,
"author_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "blog_post_slug_b95473f2" ON "blog_post" ("slug");
CREATE INDEX "blog_post_author_id_dd7a8485" ON "blog_post" ("author_id");
COMMIT;


Насколько я понял, это отложенная проверка. Это означает, что если я к примеру во время INSERT буду ссылаться на несуществующего юзера, я не должен получить ошибку. Ошибка произойдет только во время коммита. Потом, когда я добавлю этого юзера, я смогу закомитить. Вот что говорит документация:

Ограничения IMMEDIATE проверяются в конце каждого оператора, а ограничения DEFERRED откладываются до фиксации транзакции. Режим IMMEDIATE или DEFERRED задаётся для каждого ограничения независимо.


Попробовал добавить запись в таблицу с несуществующим юзером с deferred и без него. Получаю ошибку во время INSERT в обеих случаях. Почему так? Приведите пожалуйста пример, где видны отличия работы с deferred и без него.
  • Вопрос задан
  • 1773 просмотра
Подписаться 2 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
Melkij
@Melkij
PostgreSQL DBA
Ваш сгенерированный SQL невалиден для postgresql. Ключевого слова AUTOINCREMENT не существует.

А про deferred constraints:
cc=> begin;
BEGIN
cc=> insert into blog_post (author_id) values (100);
INSERT 0 1
cc=> commit;
ERROR:  insert or update on table "blog_post" violates foreign key constraint "blog_post_author_id_fkey"
ПОДРОБНОСТИ:  Key (author_id)=(100) is not present in table "auth_user".

Непосредственно insert отработал. Именно из-за deferred ограничения.
Если вы проверяете вне транзакции - то insert будет транзакцией сам по себе и потому нет разницы
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы