Django ForeignKey null = True не может удалить не нуль из столбца

Эта проблема:

Вот мой класс с двумя ForeignKey (dept и salary_range). Примечание 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)

Запуск python manage.py sqlall main, кажется, показывает правильный sql (нет NOT NULL на dept_id и 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"),

Но IntegrityError возникает при создании UserProfile:

main_userprofile.dept_id may not be NULL

И при проверке базы данных оба столбца устанавливаются NOT NULL. Как? Почему?

Взлом:

Все, что я смог придумать, это изменить таблицу после syncdb:

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

Это работает для Postgres, но sqlite не имеет опции ALTER COLUMN.

Решение ??


person kiks    schedule 07.08.2013    source источник
comment
Проверьте этот ответ   -  person karthikr    schedule 07.08.2013
comment
Вы также можете попробовать явно указать пустое значение=True и значение по умолчанию=-1.   -  person MikkoP    schedule 07.08.2013
comment
Я понимаю, что syncdb не будет изменять таблицу. Проблема существует из свежей БД.   -  person kiks    schedule 07.08.2013
comment
Спасибо, MikkoP :) Раньше я пытался использовать default=0 безрезультатно, но defualt=-1 кажется полезным.   -  person kiks    schedule 07.08.2013


Ответы (1)


Все кажется в порядке. Как указано в комментарии, скорее всего, когда вы запускали syncdb в первый раз, в то время у вас не было параметров null=True для dept и salary_range. Затем вы изменили свой код, однако это не изменило определение таблицы. Чтобы решить эту проблему, вы можете либо вручную исправить проблему, удалив часть NOT NULL, либо использовать приложения для миграции базы данных. Самый популярный — это Юг. South может обнаруживать изменения в определениях модели и вносить соответствующие изменения в вашу базу данных (так называемые миграции базы данных) без потери каких-либо данных. Южные документы довольно хороши, поэтому вы сможете начать использовать их в кратчайшие сроки.

PS. В будущих версиях Django (скорее всего, Django 1.7) возможность миграции будет интегрирована непосредственно в ядро ​​Django, однако до тех пор этим будет заниматься Юг.

person miki725    schedule 07.08.2013
comment
А, я только что осознал свою ошибку, и ваш обзор Юга установил связь. Я уже использую South для этого проекта. Моя ошибка в том, что мои производственные миграции все еще сидели без дела. Когда я делал свежий ремейк базы данных, я все еще загружал старые версии миграций! - person kiks; 07.08.2013