Field 'X' doesn't have a default value

最近在使用django框架的過程中發現一個問題,即標題所寫的“Field ‘X’ doesn't have a default value”,具體的migrations代碼如下:

migrations.AddField(
    model_name="test",
    name="user_name",
    field=models.CharField(default='xxx', max_length=64, null=True)
)

這段代碼的本意是在test表裏新増一個字段user_name,默認值是xxx,值允許爲空,執行如下命令使之生效:

django-admin migrate [app_label] [migration_name]

然後通過程序執行insert語句,當不寫user_name字段時,原以會插入NULL值,可是卻報了異常:Field 'user_name' doesn't have a default value。

查看數據庫表,該字段也是允許爲NULL。

show create table test;

得到如下結果:

create table test (
  `user_name` varchar(64),
   ...
)

關於建表時字段的NULL,NOT NULL設置,mysql create table 官方文檔如是說:

NOT NULL | NULL

If neither NULL nor NOT NULL is specified, the column is treated as though NULL had been specified.

In MySQL 5.7, only the InnoDB, MyISAM, and MEMORY storage engines support indexes on columns that can have NULL values. In other cases, you must declare indexed columns as NOT NULL or an error results.

經過測試,效果確實如其所說,執行插入語句,不寫user_name字段時,插入值爲NULL。

無奈,只得完整還原django的migrate了,利用sqlmigrate:

django-admin sqlmigrate app_label migration_name

得到開頭migration的確切sql:

alter table `test` add column `user_name` varchar(64) default 'xxx' NULL;
alter table `test` alter column 'user_name' drop default;

事情到了這裏,似乎明瞭了,因爲它drop default嘛,但是再看 mysql alter table 官方文檔,如下:

ALTER ... SET DEFAULT or ALTER ... DROP DEFAULT specify a new default value for a column or remove the old default value, respectively. If the old default is removed and the column can be NULL, the new default is NULL. If the column cannot be NULL, MySQL assigns a default value as described in Section 11.6, “Data Type Default Values”.

意思是說,如果drop default之後,該字段允許爲NULL,則NULL爲其默認值。

如果照上面所述,則不應該報“Field ‘X’ doesn't have a default value”,可是現實卻很打臉。

所以,這難道是mysql的一個BUG?抑或?

最後,問題的解決也很簡單,給該字段重新設置一個默認值即可,比如設置爲NULL。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章