0

我正在尝试让我的 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 代码没有发布数据......

关于如何解决这个问题的任何想法?

[更新]

使用“Chrome Web Store - Advanced REST client”作为测试工具:

如果我发送:

{
  "item": "temperature",
  "data": "25.00"
}

作为有效载荷 - 我得到了一个成功的 POST。

但是,如果我发送:

{
  'item': 'temperature',
  'data': '25.00'
}

作为有效载荷 - 我收到错误:

{"error":{"text":SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'item' cannot be null}}

--

4

1 回答 1

1

您从“高级 REST 客户端”发送的数据似乎是作为正文发送的 JSON 字符串。

您从 Python 代码发送的数据不是 JSON,而是 www-form-urlencoded。

如果您正确编写了服务,它会查看请求的 Content-Type 并正确处理 www-form-urlencoded 数据,或者给您一个错误,说明它不喜欢该 Content-Type。相反,您的服务只是假设除了 JSON 之外没有人会发送任何内容,无法解析 JSON 并假设您已为所有内容赋予了 null 值。

因此,您需要修复您的服务。

但与此同时,如果您想编写一个与您损坏的服务一起工作的客户端,您可以。你必须打电话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()

您可以通过使用 third-party 稍微简化这一点requests,但我认为在这种情况下,它没有足够的区别值得在 stdlib 之外进行。基本上,而不是这样:

r = urllib2.Request(url, json.dumps(params),
                    headers={'Content-Type': 'application/json'})
response = urllib2.urlopen(r).read()

......你做......</p>

r = requests.post(url, data=json.dumps(params), 
                  headers={'Content-Type': 'application/json'})
response = r.text
于 2013-10-17T00:48:57.083 回答