2011-08-18 37 views
11

Django的文档有关存储空字符串为“”,而不是在数据库级别NULL(所以只有一个空的数据可能格式)相当明确:Django的ORM,CharField和空白=真

注空字符串值将始终作为空字符串存储,而不是NULL。只对非字符串字段(如整数,布尔值和日期)使用null = True。对于这两种类型的字段,如果您希望允许表单中的空值,您还需要设置blank = True,因为null参数仅影响数据库存储(请参见空白)。

尽管如此,添加新字段后,我开始在新字段(phone_number)上遇到IntegrityErrors。

列“PHONE_NUMBER”

空值违反

这种模式看起来是这个新的领域(我执行经由南部迁移)非空约束:

class Person(models.Model): 
    user = models.ForeignKey(User) 
    description = models.TextField(blank=True) 
    phone_number = models.CharField(blank=True) 

我自从(暂时)通过在phone_number上设置null = True解决了这个问题,但现在我有数百个空字符串的条目,并且在我的数据库中有一个NULL值。 (我也尝试在phone_number字段中添加default ='',但我仍然看到IntegrityError问题。)

在过去,我一直使用MySQL,但在此项目中,我使用Postgres。生成的SQL插入尝试是:

'INSERT INTO "people_person" ("user_id", "description", "gender", "birthdate", "default_image_id", "zip_code", "beta_status") VALUES (%s, %s, %s, %s, %s, %s, %s) RETURNING "people_person"."id"'

我的期望是Django会在“phone_number”列中插入一个空白字符串,但它似乎没有这样做。我可能期望的另一件事是Django在CREATE TABLE语句中包含SET DEFAULT,但它不包含。所以Postgres对那列的NOT NULL感到愤怒。

谢谢!

回答

7

通常情况下,看似棘手的问题通常就是用户错误。

我的应用程序有两个入口点 - 两个WSGI文件,但只有一个代码库。通常情况下,如果文件被触摸,Apache将只会重新载入您的代码。我的部署脚本只触及其中一个WSGI文件 - 这意味着通过另一个WSGI文件到达我的网站的人仍然看到旧的代码。更糟的是,数据库在旧代码下被修改,但模型仍然像以前一样。

这又导致了IntegrityError问题。 Django不知道phone_number这个字段,所以即使我设置了blank=True,Django也没有插入一个空值 - 而且当然数据库认为这意味着NULL。

这导致了一系列不同的追查错误,包括上述错误。

令人惊讶的是,这些难以处理的问题多半是由于愚蠢的小漏洞造成的 - 就像我2个月前写的部署脚本,忘记了更新。

感谢读者们,我已经提出了其他答案,但我需要接受我的,因为它最终是解决方案。

6

我发现如果你明确地设置字段值为None,你仍然会得到这些错误。换句话说,default=事物在您创建python对象后立即应用,而不是在您将其保存到数据库时应用。

我想这是合理的,但有点意外。

+0

同样的事情似乎发生如果你传递一个'None'给构造函数(所以,在创建时) –