Django/Python不喜欢FloatField的None值

Jas*_*ett 2 python mysql django

Account在Django中有一个带有interest_rate属性的类(对应account.interest_rate于我的数据库).这是以下声明interest_rate:

interest_rate = models.FloatField(null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)

如果我做这样的事情,它的工作原理:

account = Account()
account.interest_rate = 5
account.save()
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做,它不起作用:

account = Account()
account.interest_rate = None
account.save()
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

Traceback (most recent call last):
  File "./import.py", line 18, in <module>
    cProfile.run('g.process()', 'prof')
  File "/usr/lib/python2.6/cProfile.py", line 29, in run
    prof = prof.run(statement)
  File "/usr/lib/python2.6/cProfile.py", line 135, in run
    return self.runctx(cmd, dict, dict)
  File "/usr/lib/python2.6/cProfile.py", line 140, in runctx
    exec cmd in globals, locals
  File "<string>", line 1, in <module>
  File "/home/jason/projects/mcifdjango/mcif/models/generic_import.py", line 34, in process
    Account.save_in_bulk(self.rows)
  File "/home/jason/projects/mcifdjango/mcif/models/account.py", line 45, in save_in_bulk
    cursor.execute(Account.bulk_insert_statement(rows))
  File "/usr/lib/pymodules/python2.6/django/db/backends/util.py", line 15, in execute
    return self.cursor.execute(sql, params)
  File "/usr/lib/pymodules/python2.6/django/db/backends/mysql/base.py", line 86, in execute
    return self.cursor.execute(query, args)
  File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 168, in execute
    if not self._defer_warnings: self._warning_check()
  File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 82, in _warning_check
    warn(w[-1], self.Warning, 3)
_mysql_exceptions.Warning: Data truncated for column 'interest_rate' at row 1
Run Code Online (Sandbox Code Playgroud)

为什么不让它在可空字段上保存null?我做错了吗?

Ken*_*ane 6

该字段在mysql中是否可以为空?

我在过去看到这个错误时,我创建了一个模型,其中一个字段最初不允许为空,当创建表时,然后更改为允许它可为空.由于mysql从原始表创建中设置了null = false,因此即使django允许,它也会使插入失败.

要解决这个问题,我会检查mysql中的表定义,如果该字段为null = false,您可以手动更改它,或者您可以删除该表(如果您不关心数据),然后重新运行. /manage.py syncdb重新创建表.

如果您使用south来管理架构迁移,则可以创建新的架构迁移,然后运行该迁移.

如果mysql表实例没有显示null = false,那么它就是其他东西.

更新: 我们发现mysql的列可以为空,所以我正在更新答案.

我正在使用Django 1.2.5版,您使用哪个版本?

我在我的系统中创建了模型.

from django.db import models

#================================================================================
class Account(models.Model):
    interest_rate = models.FloatField(null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)

然后通过shell运行它,它对我有用.

Python 2.6.6 (r266:84292, Sep  8 2010, 16:19:33) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from aggra.models import Account
>>> account = Account()
>>> account.interest_rate = None
>>> account.save()
>>> exit()
Run Code Online (Sandbox Code Playgroud)

这是我从django创建的声明.aggra是我的应用名称.

$ python manage.py sql aggra
BEGIN;
CREATE TABLE `aggra_account` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `interest_rate` double precision
)
;
COMMIT;
Run Code Online (Sandbox Code Playgroud)

这是我的表从mysql看起来的样子.

CREATE TABLE `aggra_account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `interest_rate` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)

这看起来像你的吗?

更新2 我们发现它看起来一样,使用的是大致相同版本的django和python.

你的mysql版本是什么?

你对SQL模式有什么看法?我的是空的.

mysql> show variables where Variable_name = 'sql_mode';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |
+---------------+-------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

如果你将它设置为严格,那么你需要将其更改为更宽松.

http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html

也可以看看.

http://forums.mysql.com/read.php?11,132672,132693#msg-132693