Opened 9 years ago

Closed 9 years ago

#5113 closed (duplicate)

Foreign key not created for class "Project"

Reported by: Darren <spaceship@…> Owned by: Philippe Raoult
Component: Database layer (models, ORM) Version: master
Severity: Keywords: foreign key backend
Cc: Triage Stage: Design decision needed
Has patch: no Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: UI/UX:

Description

Foreign keys look like they're not being created correctly if the class is named "Project".

Here's sample code:

from django.db import models

class Client(models.Model):
    name = models.CharField(maxlength=200)
    shortname = models.CharField('short name', maxlength=5)
    datecreated = models.DateTimeField('date created')

class Project(models.Model):
    client = models.ForeignKey(Client)
    name = models.CharField(maxlength=200)
    datecreated = models.DateTimeField('date created')

Results in this:

C:\temp\django\temp\timeserver>manage.py sql timesheet
BEGIN;
CREATE TABLE "timesheet_project" (
    "id" integer NOT NULL PRIMARY KEY,
    "client_id" integer NOT NULL,
    "name" varchar(200) NOT NULL,
    "datecreated" datetime NOT NULL
);
CREATE TABLE "timesheet_client" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(200) NOT NULL,
    "shortname" varchar(5) NOT NULL,
    "datecreated" datetime NOT NULL
);
COMMIT;

Note lack of foreign key relationship on timesheet_project.client_id

However (note class Project renamed to Projecta) works:

from django.db import models

class Client(models.Model):
    name = models.CharField(maxlength=200)
    shortname = models.CharField('short name', maxlength=5)
    datecreated = models.DateTimeField('date created')

class Projecta(models.Model):
    client = models.ForeignKey(Client)
    name = models.CharField(maxlength=200)
    datecreated = models.DateTimeField('date created')

Results in this:

C:\temp\django\temp\timeserver>manage.py sql timesheet

BEGIN;
CREATE TABLE "timesheet_client" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(200) NOT NULL,
    "shortname" varchar(5) NOT NULL,
    "datecreated" datetime NOT NULL
);
CREATE TABLE "timesheet_projecta" (
    "id" integer NOT NULL PRIMARY KEY,
    "client_id" integer NOT NULL REFERENCES "timesheet_client" ("id"),
    "name" varchar(200) NOT NULL,
    "datecreated" datetime NOT NULL
);
COMMIT;

Environment:

Python 2.5.1, Windows Vista, Django 0.96, sqlite3 database

Change History (7)

comment:1 Changed 9 years ago by James Bennett

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset

This is arguably the correct thing to do; SQLite parses and accepts declarations of FOREIGN KEY constraints, but does not enforce them or base any functionality on them.

comment:2 Changed 9 years ago by James Bennett

Wait, no, missed the second bit. That is a bit weird.

comment:3 Changed 9 years ago by Peter Baumgartner

Keywords: sqlite3 removed
Summary: Foreign key not created for class "Project" using sqlite 3Foreign key not created for class "Project"
Version: 0.96SVN

Problem does not appear to be SQLite dependent. Confirmed on both MySQL 4.1.22 and SQLite 3.3.16

comment:4 Changed 9 years ago by Philippe Raoult

Component: Core frameworkDatabase wrapper
Keywords: foreign key backend added
Needs tests: set
Owner: changed from nobody to Philippe Raoult
Status: newassigned
Triage Stage: UnreviewedAccepted

confirmed in SVN. It appears to be related to the order in which the models are outputed in SQL. If Project model is defined first, it won't have the FK. If it is defined after it will. The order seems to be related to the name but I don't know how exactly (probably a dict ordering?).

comment:5 Changed 9 years ago by Philippe Raoult

a similar issue is mentionned in #4930 (this time with models in different apps).

comment:6 Changed 9 years ago by Philippe Raoult

Status: assignednew
Triage Stage: AcceptedDesign decision needed

comment:7 Changed 9 years ago by Philippe Raoult

Resolution: duplicate
Status: newclosed

dup of #4193 which is more documented.

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