Opened 15 years ago
Closed 15 years ago
#12210 closed (wontfix)
sqlite backend: REFERENCES clause not created with quoted ForeignKey field
Reported by: | 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: | no | UI/UX: | no |
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?
Note:
See TracTickets
for help on using tickets.
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.