python,django,向mysql更新数据时save()报错不能用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python,django,向mysql更新数据时save()报错不能用相关的知识,希望对你有一定的参考价值。

求大神帮忙,models.py中有个Student类,当我用s = Student(...)创建对象,然后s.save()可以往mysql中插入记录,但是当我用 s.name = 'aaa',想更新的时候,调用s.save()就报错了.错误代码如下,望大家解答一下.

>>> s.save()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "D:\Program Files (x86)\Python27\lib\site-packages\django\db\models\base.
py", line 431, in save
self.save_base(force_insert=force_insert, force_update=force_update)
File "D:\Program Files (x86)\Python27\lib\site-packages\django\db\models\base.
py", line 495, in save_base
rows = manager.filter(pk=pk_val)._update(values)
File "D:\Program Files (x86)\Python27\lib\site-packages\django\db\models\query
.py", line 446, in _update
query.add_update_fields(values)
File "D:\Program Files (x86)\Python27\lib\site-packages\django\db\models\sql\s
ubqueries.py", line 249, in add_update_fields
val = field.get_db_prep_save(val)
File "D:\Program Files (x86)\Python27\lib\site-packages\django\db\models\field
s\__init__.py", line 202, in get_db_prep_save
return self.get_db_prep_value(value)
File "D:\Program Files (x86)\Python27\lib\site-packages\django\db\models\field
s\__init__.py", line 446, in get_db_prep_value
return self.to_python(value)
File "D:\Program Files (x86)\Python27\lib\site-packages\django\db\models\field
s\__init__.py", line 442, in to_python
ugettext_lazy("This field cannot be null."))
ValidationError: <django.utils.functional.__proxy__ object at 0x0000000002F26320
>
在shell下:s1 = Student(...) #插入数据s1.save() 这个插入正常s2 = Student.objects.get(studentid = 1) 返回正常s2.name 打印正常s2.name = 'asdf's2.save() 报错了

参考技术A ValidationError 提示的是validation error,应该是某些field是not null的,你没有给它赋值。建议贴上Student的model源码以及你实际操作的语句。追问

已经贴上去了,麻烦你再帮我看下。

追答

你看下是不是必要的field没有赋值呢? s1 = Student(...)这一句能具体看下赋值了哪些变量么? django 里面blank=True不包含null=True的,所以一些field即使blank=True,只要没有声明null=True,同样不能留白。

参考技术B 把s2的所有字段Log出来看一眼.
再就是 常量字符串,特别是里面有非ASCII字符的,前面都加上u,windows没有U可以自动转换,Linux下面有的时候自动转不过去。
参考技术C 插入记录用的是 INSERT 语句,更新是UPDATE语句,是不是混用了?【不确定追问

不是啊,django下更新表都是用save而已

参考技术D 我在自己的上面做了 ,没有发现错误呢。如果可以的话,你把你的整个代码发上来看看呢。

从 ADS1115 Python 向 MySQL 插入数据

【中文标题】从 ADS1115 Python 向 MySQL 插入数据【英文标题】:Insert Data to MySQL From ADS1115 Python 【发布时间】:2017-01-07 15:04:39 【问题描述】:

我在使用 ADC ADS1115 从树莓派中的加速度计传感器提取数据时遇到问题。

我正在使用此代码将数据插入到 mysql

# Author: Tony DiCola
# License: Public Domain
# Import the ADS1x15 module.
import Adafruit_ADS1x15
import MySQLdb
import time
import datetime
# Create an ADS1115 ADC (16-bit) instance.
adc = Adafruit_ADS1x15.ADS1115()
# Or create an ADS1015 ADC (12-bit) instance.
#adc = Adafruit_ADS1x15.ADS1015()

# Note you can change the I2C address from its default (0x48), and/or the I2C
# bus by passing in these optional parameters:
#adc = Adafruit_ADS1x15.ADS1015(address=0x49, busnum=1)

# Choose a gain of 1 for reading voltages from 0 to 4.09V.
# Or pick a different gain to change the range of voltages that are read:
#  - 2/3 = +/-6.144V
#  -   1 = +/-4.096V
#  -   2 = +/-2.048V
#  -   4 = +/-1.024V
#  -   8 = +/-0.512V
#  -  16 = +/-0.256V
# See table 3 in the ADS1015/ADS1115 datasheet for more info on gain.
GAIN = 1

time_sensor = time.time()
# Main loop.
x = [1]*4
y = [2]*4
z = [3]*4   
for i in range(4):
    x[i] = adc.start_adc(i, gain=GAIN)
    y[i] = adc.start_adc(i, gain=GAIN)
    z[i] = adc.start_adc(i, gain=GAIN)
# Read the specified ADC channel using the previously set gain value.
# Once continuous ADC conversions are started you can call get_last_result() to
db = MySQLdb.connect("localhost", "root", "raspberry", "sensor_log")
curs=db.cursor()

while True:
    try:
        curs.execute("""INSERT INTO table_sensor_log(time, koordinatx, koordinaty, koordinatz) 
        values(%s,%s,%s,%s)""",(time_sensor,x[i],y[i],z[i]))
        db.commit()
    except:
        print "Error"
        db.rollback()
    time.sleep(1)
db.close()

问题是当我运行该脚本时,接收到的数据是重复的,该脚本仅从加速度传感器的第一个数据中获取数据,然后重复插入。

这就是我得到的。

+-------+------------+------------+------------+------------+
| id    | time       | koordinatX | koordinatY | koordinatZ |
+-------+------------+------------+------------+------------+
| 24743 | 1472624612 |      15443 |      20351 |      20454 |
| 24744 | 1472624612 |      15443 |      20351 |      20454 |
| 24745 | 1472624612 |      15443 |      20351 |      20454 |
| 24746 | 1472624612 |      15443 |      20351 |      20454 |
| 24747 | 1472624612 |      15443 |      20351 |      20454 |
| 24748 | 1472624612 |      15443 |      20351 |      20454 |
+-------+------------+------------+------------+------------+

我需要传感器的真实数据,如果我使用打印,数据会正确显示,但是当我将它插入到 mysql 时,数据会这样。

【问题讨论】:

【参考方案1】:

在循环内移动光标初始化

while True:
    try:
        curs=db.cursor()
        curs.execute("""INSERT INTO table_sensor_log(time, koordinatx, koordinaty, koordinatz) 
        values(%s,%s,%s,%s)""",(time_sensor,x[i],y[i],z[i]))
        db.commit()
        curs.close()
    except:
        print "Error"
        db.rollback()
    time.sleep(1)

【讨论】:

能否在 curs.execute(..) 之前添加 printf 并检查结果? 结果是重复的,但是当我尝试使用命令 python script.py 手动运行脚本时,mysql 上的值是不同的,而不是重复的。我尝试使用 watch 命令和 crontab 每秒自动运行脚本,但这会减慢服务器的速度。 @sr3z【参考方案2】:

ads1115 只有一个模拟阅读器,您会看到 4 个模拟引脚,但都通过多路复用器连接了一个模拟阅读器, 因此,当您尝试将 pin0 读取到 pin1 多路复用器单元时,需要时间进行转换。对于一点点你必须延迟,可能是 10 微秒。 您可以在数据表 ads1115 上看到,在连续模式下读取 860。连续模式意味着您只需读取一个引脚。如果您在 ads1115 上阅读 4 pin,您必须等待

【讨论】:

以上是关于python,django,向mysql更新数据时save()报错不能用的主要内容,如果未能解决你的问题,请参考以下文章

通过 Django Channels 和 Websockets 向客户端推送实时更新

根据 Django 通道中的数据库事件向用户发送数据

更新主键 Django MySQL

Python基础之 Django模型

如何使用 jQuery 向 django 服务器发出请求以刷新页面上的信息

在 django、python2 中更新数据库之前返回 JSONResponse