【问题标题】:How do I insert a row in my google fusion table using Python如何使用 Python 在我的谷歌融合表中插入一行
【发布时间】:2013-02-25 22:11:12
【问题描述】:

我正在处理一个项目,其中一部分涉及从 python 脚本将行插入到项目的 Google Fusion Table 中。在过去的几天里,我一直在试图弄清楚如何做到这一点,但我很困惑。

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

我遇到的第二个问题是我并不真正了解如何在表中插入一行代码。我在上面找到的大部分材料都来自已弃用的 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,我只是不确定我的代码需要更改哪些内容才能实现。 对不起,我是菜鸟。

第二次编辑:

很抱歉让这个时间变长了,但我觉得有必要展示一下我到目前为止的进展情况。我切换到图书馆请求,事情变得更容易了,但是我仍然没有成功发布 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."
 }
}

【问题讨论】:

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


    【解决方案1】:

    如果您的应用程序需要离线访问 Google API,则对授权码的请求应包含 access_type 参数,其中该参数的值为离线。

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

    然后,要使用刷新令牌获取访问令牌,您需要发送一个包含 grant_type 和值为 refresh_token 的 POST 请求。

    基本上,SQL 的工作方式是使用 SQL 语句的子集 https://www.googleapis.com/fusiontables/v1/query?sql=STATEMENT_HERE 发送 POST 请求

    参考

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

    编辑:

    由于您使用没有数据参数的urllib2,它默认为 GET。要解决此问题,您应该使用另一个允许显式指定方法的 HTTP 库(如 requestshttplib)或执行以下操作:

    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
    

    重要提示:

    1. Monkey 修补方法以执行我们想要的操作(POST 使用空主体),否则我们将收到 HTTP Error 400: HTTP GET can only be used for SELECT queries

    2. 手动指定我们没有正文(Content-Length0)否则我们会收到 HTTP Error 411: Length Required

    3. 必须使用内有单引号的双引号转义内引号才能通过查询提交字符串。换句话说,"INSERT INTO %s(EXAMPLE_COL1,EXAMPLE_COL2) VALUES(EXAMPLE_INFO1,EXAMPLE_INFO2)" % table_id 不起作用。

      如果我们尝试使用前一行,我们会得到类似HTTP Error 400: Parse error near 'SOME_STRING' (line X, position Y)

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

    Is there any way to do HTTP PUT in python

    【讨论】:

    • 好的,我现在获取刷新令牌没有问题,但我仍然坚持在我的融合表中插入一行的代码是什么样的。
    • 你能发布你目前所拥有的吗?你得到什么错误?这有点奇怪,因为您使用 POST 但您根本不使用正文(它的空白)。信息会像 GET 请求一样提交。
    • 创建开瓶器不起作用,我遇到了一些我无法克服的错误。所以我转而尝试请求。结果是执行 GET 请求非常简单且有效,但我对 POST 没有任何运气。
    • 哇,好的,第 3 点完全是我的问题!我现在可以发出 POST 请求。我真的很感谢你抽出时间来帮助我。谢谢!
    猜你喜欢
    • 2014-06-06
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多