我正在尝试让我的Raspberry Pi记录温度数据并将其发布到自托管的RESTful API。
我在向API成功发布数据时遇到问题 - 这是我的代码:
[rPi Python代码]
import urllib
import urllib2
url = 'http://doopcreations.com/raspberry/api/data'
params = urllib.urlencode({
'item': 'temperature',
'data': '25.00'
})
print("Posting data: " + params)
response = urllib2.urlopen(url, params).read()
print(response)
这给了我一个错误:
{“error”:{“text”:SQLSTATE [23000]:完整性约束违规:1048列'item'不能为空}}
注意: 我也尝试更新我的数据库以允许NULL值 - 这导致只插入空值 - 即/似乎我的python代码不发布数据.......
关于我如何解决这个问题的任何想法?
[UPDATE]
使用“Chrome网上应用店 - 高级REST客户端”作为测试工具:
如果我发送:
{
"item": "temperature",
"data": "25.00"
}
作为有效载荷 - 我获得了成功的POST。
但是,如果我发送:
{
'item': 'temperature',
'data': '25.00'
}
作为有效载荷 - 我收到错误:
{"error":{"text":SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'item' cannot be null}}
-
答案 0 :(得分:1)
您从“高级REST客户端”发送的数据似乎是作为正文发送的JSON字符串。
您从Python代码发送的数据不是JSON,而是www-form-urlencoded。
如果您正确编写了服务,它会查看请求的Content-Type并正确处理www-form-urlencoded数据,或者给出错误,说明它不喜欢Content-Type。相反,您的服务只是假设除了JSON之外没有人会发送任何内容,无法解析JSON并假设您已为所有内容赋予空值。
所以,你需要修复你的服务。
但与此同时,如果你想写一个与你破损服务一起工作的客户端,你可以。您必须致电json.dumps(params)
而不是urllib.urlencode(params)
。您也不能再使用单行urlopen
了。像这样:
params = {
'item': 'temperature',
'data': '25.00'
}
r = urllib2.Request(url, json.dumps(params),
headers={'Content-Type': 'application/json'})
response = urllib2.urlopen(r).read()
你可以通过使用第三方requests
来简化这一点,但我不认为在这种情况下值得超出stdlib的价值。基本上,而不是:
r = urllib2.Request(url, json.dumps(params),
headers={'Content-Type': 'application/json'})
response = urllib2.urlopen(r).read()
...你做......
r = requests.post(url, data=json.dumps(params),
headers={'Content-Type': 'application/json'})
response = r.text