Opened 5 years ago

Closed 5 years ago

#12210 closed (wontfix)

sqlite backend: REFERENCES clause not created with quoted ForeignKey field

Reported by: xicmiah@… Owned by: nobody
Component: Database layer (models, ORM) Version: 1.1
Severity: Keywords: ForeignKey
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

When using ForeignKey field with quoted class argument, if related class is defined later in code, in SQL output, REFERENCES clause is not created for that field.

So, with this models.py:

from django.db import models

class A(models.Model):
    name = models.CharField(max_length=5)
    ref = models.ForeignKey('B')

class B(models.Model):
    name = models.CharField(max_length=5)

python manage.py sqlall writes this:

BEGIN;
CREATE TABLE "tst_a" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(5) NOT NULL,
    "ref_id" integer NOT NULL
)
;
CREATE TABLE "tst_b" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(5) NOT NULL
)
;
CREATE INDEX "tst_a_ref_id" ON "tst_a" ("ref_id");
COMMIT;

Namely, there is no REFERENCES clause on ref_id field.

If the classes are swapped, everything is fine:
models.py:

from django.db import models

class B(models.Model):
    name = models.CharField(max_length=5)

class A(models.Model):
    name = models.CharField(max_length=5)
    ref = models.ForeignKey('B')

sqlall:

BEGIN;
CREATE TABLE "tst_b" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(5) NOT NULL
)
;
CREATE TABLE "tst_a" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(5) NOT NULL,
    "ref_id" integer NOT NULL REFERENCES "tst_b" ("id")
)
;
CREATE INDEX "tst_a_ref_id" ON "tst_a" ("ref_id");
COMMIT;

Is this behavior intended?

Change History (1)

comment:1 Changed 5 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to wontfix
  • Status changed from new to closed

Intended isn't perhaps the right description, but it is correct (or rather, isn't wrong).

SQLite doesn't have row referential integrity, so the REFERENCES statement doesn't actually do anything. The fact that it is generated at all is strictly an error, but it's a transparent one, because SQLite parses and ignores REFERENCES statements.

When you use quoted notation for fields, the field is put on a list of fields which must have their references updated later. On Postgres, this will result in a bunch of ALTER TABLE statements in sqlall; on SQLite, we know that references aren't needed, so those statements aren't generated.

Note: See TracTickets for help on using tickets.
Back to Top