A
A
AndreyRafalsky1322019-09-24 16:59:40
PostgreSQL
AndreyRafalsky132, 2019-09-24 16:59:40

Why is DEFERRABLE INITIALLY DEFERRED needed as a result of sqlmigrate for model add migration?

Can you please tell me why DEFERRABLE INITIALLY DEFERRED is used when creating a model table? This is the result I got:

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;

As far as I understand, this is a delayed check. This means that if, for example, I refer to a non-existent user during INSERT, I should not get an error. The error will only occur during the commit. Then, when I add this user, I can commit. Here's what the documentation says:
IMMEDIATE constraints are checked at the end of each statement, while DEFERRED constraints are deferred until the transaction commits. The IMMEDIATE or DEFERRED mode is set for each constraint independently.

I tried to add an entry to the table with a non-existent user with and without deferred. I get an error during INSERT in both cases. Why is that? Please give an example where you can see the differences between working with and without deferred.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Melkij, 2019-09-24
@melkij

Your generated SQL is not valid for postgresql. The AUTOINCREMENT keyword does not exist.
And about 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".

Directly insert fulfilled. It's because of the deferred constraint.
If you check outside of a transaction - then insert will be a transaction in itself and therefore there is no difference

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question