如何使用Python在我的google fusion表中插入一行

时间:2013-03-10 19:40:25

标签: python google-api oauth-2.0 urllib2 google-fusion-tables

我正在开发一个项目,其中一部分涉及从python脚本中将行插入到项目的Google Fusion Table中。我花了最近几天试图找出如何做到这一点,我正式感到困惑。

我的研究似乎表明我需要使用Oauth 2.0来访问API。这样做我可以成功获得访问令牌,但我似乎无法成功获得刷新令牌。我不确定这是否会妨碍我使用Python代码成功集成Fusion表的访问权限。

我遇到的第二个问题是我真的不明白如何在我的表中插入一行代码。我在其上发现的大多数材料来自不推荐使用的Fusion Tables SQL API,我并不完全了解这种新方法。

我是这方面的初学者,非常感谢帮助我的任何方向!

编辑: 所以到目前为止我工作的代码看起来像这样:

client_id = "<client_i>"
client_secret = "<client_secret>"
table_id = "<table_id>"

access_token = ""
refresh_token = "<refresh_token>"

#   the refresh token is used to request a new access token
data = urllib.urlencode({
  'client_id': client_id,
  'client_secret': client_secret,
  'refresh_token': refresh_token,
  'grant_type': 'refresh_token'})
request = urllib2.Request(
  url='https://accounts.google.com/o/oauth2/token',
  data=data)
request_open = urllib2.urlopen(request)
response = request_open.read()
request_open.close()
tokens = json.loads(response)
access_token = tokens['access_token']

#   Read the table
request_read = urllib2.Request(
  url='https://www.google.com/fusiontables/api/query?%s' % \
    (urllib.urlencode({'access_token': access_token,
                       'sql': 'SELECT * FROM table_id'})))
request_open = urllib2.urlopen(request_read)
response = request_open.read()
request_open.close()
print response

我的代码试图在我的表中插入一个新行:

date = str(datetime.now().date())
time = str(datetime.now().time())
query = 'INSERT INTO table_id (Date,Time,Saskatoon,Regina,MeadowLake)VALUES(date,time,60.01,60.02,59.99)'
data = urllib2.Request(
  url='https://www.google.com/fusiontables/api/query?%s' % \
    (urllib.urlencode({'access_token': access_token,
                       'sql': query})))
request_open = urllib2.urlopen(data)

当我跑这个时,我得到了

  

HTTP错误400:HTTP GET只能用于选择查询。

我知道我应该为INSERT做一个POST而不是GET,我只是不确定我的代码需要改变什么才能实现。 抱歉是个菜鸟。

2ND编辑:

很抱歉让这个更长,但我觉得显示我到目前为止所处的位置是相关的。我切换到库请求,事情变得有点容易,但我仍然没有成功发布POST。我导入行的新代码如下:

def importRows(self):
    print 'IMPORT ROWS'
    date = str(datetime.now().date())
    time = str(datetime.now().time())
    data = {'Date': date,
            'Time': time,
            'Saskatoon': '60.01',
            'Regina': '59.95'}
    url = 'https://www.googleapis.com/upload/fusiontables/v1/tables/%s/import/%s' % \
          (tableid, self.params) # self.params is access token
    importRow = requests.post(url, params=data)

    print importRow.status_code
    print importRow.text

哪个给了我

400
{
 "error": {
  "errors": [
   {
    "domain": "fusiontables",
    "reason": "badImportInputEmpty",
    "message": "Content is empty."
   }
  ],
  "code": 400,
  "message": "Content is empty."
 }
}

1 个答案:

答案 0 :(得分:1)

  

如果您的应用需要离线访问Google API,则授权代码请求应包含access_type参数,其中该参数的值处于脱机状态。

https://developers.google.com/accounts/docs/OAuth2WebServer#offline

然后,要使用刷新令牌获取访问令牌,您需要发送包含值grant_type的{​​{1}}的POST请求。

基本上,SQL的工作方式是使用SQL语句的子集发送POST请求refresh_token

参阅

https://developers.google.com/fusiontables/docs/v1/reference/query https://developers.google.com/fusiontables/docs/v1/sql-reference

编辑:

由于您使用https://www.googleapis.com/fusiontables/v1/query?sql=STATEMENT_HERE而没有数据参数,因此默认为GET。要解决此问题,您应该使用另一个允许显式指定方法的HTTP库(如requestsurllib2)或执行以下操作:

httplib

重要提醒:

  1. 猴子修补方法做我们想要的事情(用空身体POST)否则我们会收到query = "INSERT INTO %s(EXAMPLE_COL1,EXAMPLE_COL2) VALUES"\ "('EXAMPLE_INFO1','EXAMPLE_INFO2')" % table_id # Single quotes opener = urllib2.build_opener(urllib2.HTTPHandler) request = urllib2.Request('https://www.google.com/fusiontables/api/query?%s' % \ (urllib.urlencode({'access_token': access_token, 'sql': query})), headers={'Content-Length':0}) # Manually set length to avoid 411 error request.get_method = lambda: 'POST' # Change HTTP request method response = opener.open(request).read() print response

  2. 手动指定我们没有正文(HTTP Error 400: HTTP GET can only be used for SELECT queriesContent-Length),否则我们会收到0

  3. 必须使用双引号内的单引号转义内部引号以通过查询提交字符串。换句话说,HTTP Error 411: Length Required不起作用。

    如果我们尝试使用上一行,我们会得到类似"INSERT INTO %s(EXAMPLE_COL1,EXAMPLE_COL2) VALUES(EXAMPLE_INFO1,EXAMPLE_INFO2)" % table_id

  4. 的内容

    有关使用urllib2更改方法的信息,请参阅:

    Is there any way to do HTTP PUT in python