Question

The problem:

Here's my class with two ForeignKeys (dept and salary_range). Note null=True:

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='user_profile')
    avatar = models.CharField(max_length=300, default='/static/default.png')
    dept = models.ForeignKey(Department, null=True)
    salary_range = models.ForeignKey(SalaryRange, null=True)

Running python manage.py sqlall main seems show the correct sql (no NOT NULL on dept_id and salary_range_id:

CREATE TABLE "main_userprofile" (
    "id" integer NOT NULL PRIMARY KEY,
    "user_id" integer NOT NULL UNIQUE REFERENCES "auth_user" ("id"),
    "avatar" varchar(300) NOT NULL,
    "dept_id" integer REFERENCES "main_department" ("id"),
    "salary_range_id" integer REFERENCES "main_salaryrange" ("id"),

But an IntegrityError occurs when creating a UserProfile:

main_userprofile.dept_id may not be NULL

And upon inspection of the database, both columns are set NOT NULL. How? Why?

The hack:

All I have been able to come up with is to alter the table after syncdb:

ALTER TABLE main_userprofile ALTER COLUMN dept_id DROP NOT NULL;
ALTER TABLE main_userprofile ALTER COLUMN salary_range_id DROP NOT NULL;

This works for Postgres, but sqlite does not have an ALTER COLUMN option..

The Solution ??

Was it helpful?

Solution

Everything seems fine. As suggested in the comment, most likely when you ran syncdb the first time, at that time you did not had the options null=True for dept and salary_range. Then you changed your code however that did not modify the table definition. To solve that, you can either manually fix the issue by dropping the NOT NULL part or you can use database migrations apps. The most popular one is by far South. South can detect changes in the model definitions and apply appropriate changes to your database (called database migrations) without loosing any data. South docs are pretty good so you should be able to start using it in no time.

PS - In future versions of Django (most likely Django 1.7), the migrations capability will be integrated directly into Django core however until then, South will have to do.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top