Django South 迁移不适用于 null = True 和空白 = True

Posted

技术标签:

【中文标题】Django South 迁移不适用于 null = True 和空白 = True【英文标题】:Django South migration not working with null = True and blank = True 【发布时间】:2012-03-22 09:20:56 【问题描述】:

我正在使用 South 和 Django 进行数据库迁移。

在我的models.py 中,我更改了其中一个字段

class User(models.Model):
    group = models.ForeignKey(Group)

class User(models.Model):
    group = models.ForeignKey(Group, null = True, blank = True)

换句话说,我想将Usergroup 字段设为可选。

然后当我尝试运行架构迁移时,South 给了我这个错误

(doors)hobbes3@hobbes3:~/Sites/mysite$ python manage.py schemamigration doors --auto
 ? The field 'User.group' does not have a default specified, yet is NOT NULL.
 ? Since you are making this field nullable, you MUST specify a default
 ? value to use for existing rows. Would you like to:
 ?  1. Quit now, and add a default to the field in models.py
 ?  2. Specify a one-off value to use for existing columns now
 ?  3. Disable the backwards migration by raising an exception.
 ? Please select a choice: 

为什么南方抱怨?我不是用null = Trueblank = True 指定了默认的NULL 吗?

如果这很重要,这就是我当前的表在doors_user 中的样子

mysite=# \d doors_user
                                    Table "public.doors_user"
   Column    |           Type           |                        Modifiers                        
-------------+--------------------------+---------------------------------------------------------
 id          | integer                  | not null default nextval('doors_user_id_seq'::regclass)
 group_id    | integer                  | not null
 user_type   | character varying(1)     | not null default 't'::character varying
 comment     | text                     | not null
 email       | character varying(75)    | not null
 password    | character varying(135)   | not null
 first_name  | character varying(135)   | not null
 last_name   | character varying(135)   | not null
 phone       | character varying(135)   | not null
 status      | character varying(1)     | not null default 'p'::character varying
 location_id | integer                  | 
 t_created   | timestamp with time zone | not null
 t_modified  | timestamp with time zone | not null
Indexes:
    "doors_user_pkey" PRIMARY KEY, btree (id)
    "doors_user_group_id" btree (group_id)
    "doors_user_location_id" btree (location_id)
Foreign-key constraints:
    "group_id_refs_id_2fde5e861cc0e5fe" FOREIGN KEY (group_id) REFERENCES doors_group(id) DEFERRABLE INITIALLY DEFERRED
    "location_id_refs_id_13c85dcc5cba5e23" FOREIGN KEY (location_id) REFERENCES doors_location(id) DEFERRABLE INITIALLY DEFERRED
Referenced by:
    TABLE "doors_property" CONSTRAINT "owner_id_refs_id_7a3a10af3eba8739" FOREIGN KEY (owner_id) REFERENCES doors_user(id) DEFERRABLE INITIALLY DEFERRED
    TABLE "doors_order" CONSTRAINT "user_action_id_refs_id_79506d7c5228f713" FOREIGN KEY (user_action_id) REFERENCES doors_user(id) DEFERRABLE INITIALLY DEFERRED
    TABLE "doors_order" CONSTRAINT "user_created_id_refs_id_79506d7c5228f713" FOREIGN KEY (user_created_id) REFERENCES doors_user(id) DEFERRABLE INITIALLY DEFERRED
    TABLE "doors_log" CONSTRAINT "user_id_refs_id_3ce582a126688737" FOREIGN KEY (user_id) REFERENCES doors_user(id) DEFERRABLE INITIALLY DEFERRED
    TABLE "doors_ordercomment" CONSTRAINT "user_id_refs_id_6d10d6e79572e14d" FOREIGN KEY (user_id) REFERENCES doors_user(id) DEFERRABLE INITIALLY DEFERRED

还有SELECT 声明

mysite=# select * from doors_user;
 id | group_id | user_type | comment |      email       | password | first_name | last_name | phone | status | location_id |          t_created           |          t_modified           
----+----------+-----------+---------+------------------+----------+------------+-----------+-------+--------+-------------+------------------------------+-------------------------------
  1 |        1 | w         |         | blah12@gmail.com | ads      | Michael    | Anderson  |       | a      |             | 2012-03-04 06:44:44.97263-05 | 2012-03-04 06:44:44.972661-05
(1 row)

【问题讨论】:

我通过选择选项 #3 绕过了这个问题,但我仍然想知道 South 为什么抱怨... 只是对您的代码的注释,除了逗号之外,括号中的空格是不好的。不是必需的,但它符合 python 风格标准,并且可读性更好。 @tushar747 是的,这是旧代码。我不再那样写了。我已经更新了样式。谢谢! 【参考方案1】:

我认为... South 正在考虑以防您想将迁移回滚到您的迁移时间

class User(models.Model):
    group = models.ForeignKey(Group)

在这种情况下,如果回滚,默认值将是多少。您选择了选项 #3,我相信它会禁用回滚到该迁移的能力,从而以这种方式解决您的问题。

【讨论】:

嗯,这有点道理......但我认为 South 应该只在我将(可以是)NULL 外键更改回 NOT NULL 外键时发出警告。除了你怎么想有一个默认的外键呢?选择一个随机 ID? 你是对的。我经常想知道我应该如何为 FK 选择默认值。我遇到了很多麻烦,有时因此不得不重做我的数据。我首先在 FK 表中创建了一个项目,然后如果需要,我使用默认值运行我的迁移。我敢肯定这不是最好的方法。

以上是关于Django South 迁移不适用于 null = True 和空白 = True的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 1.7 迁移之前运行 South 迁移的推荐方法是啥?

从 South 迁移到 Django 1.7 迁移:可交换依赖项

Django 迁移——是不是可以在项目中间使用 South?

如何对 Django South“数据迁移”进行单元测试

South - 将 django 应用程序从 sqlite 迁移到 mysql

不知道为啥 django South 试图运行反向迁移