我正在开发一个谷歌应用程序脚本功能,将插入一行到一个融合表。我的大多数融合表接口工作得很好,但这是我第一次尝试在一个sql 'POST'查询。根据这里的文档,我应该能够将sql语句放入POST主体中。我已经将自己减少到OAuth Playground进行故障排除,并且不断得到以下错误。我一直在尝试使用sql插入语句sql=INSERT INTO {fusionId} (HeadingName) VALUES (ValueOne)
,我已经尝试了这个语句的各种变体,但无济于事。请帮我确定正确的语法或方法来做到这一点。
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Required parameter: sql",
"locationType": "parameter",
"location": "sql"
}
],
"code": 400,
"message": "Required parameter: sql"
}
}
一旦我弄清楚了这一点,我就需要在我的代码中复制游乐场操作,(我认为)看起来像这样:
function fusionRequest(methodType, sql, oAuthFields) {
OAL.googleAuth(oAuthFields);
var options =
{
oAuthUseToken : "always",
oAuthServiceName : 'fusiontables',
method : "POST",
payload : "sql=INSERT INTO {fusionId} (Heading) VALUES (ONE)",
contentType : "application/json"
};
Logger.log(options)
var fetchResult = UrlFetchApp.fetch(oAuthFields.queryUrl, options);
return JSON.parse(fetchResult.getContentText());
}
我一直认为这也可能是内容类型的问题,但我不知道。请帮助。
Update # 1 通过使用三亚的建议,我能够让请求在OAuth Playground中工作。然而,我仍然在努力与代码中的请求。在运行代码时,我得到了重复的授权请求(或在调试时出现一般OAuth错误)。从我以前的经验来看,我认为这意味着我的有效负载仍然存在一些问题。如有任何建议,我将不胜感激。
var oAuthFields = {
'clientId' : '523606257547.apps.googleusercontent.com',
'scope' : 'https://www.googleapis.com/auth/fusiontables',
'fetchUrl' : 'https://www.googleapis.com/fusiontables/v1/',
'clientSecret' : 'L-f8DgwK4rs7Qmw9k5IFL7lZ',
'fusionId' : '1b4kT_aYRfNBy8ZPtSZqhQUqVSVIYj_QWiBmjXXI',
'service' : 'fusiontables',
'queryUrl' : 'https://www.googleapis.com/fusiontables/v1/query/'
};
function fusionRequest(methodType, sql, oAuthFields) {
OAL.googleAuth(oAuthFields);
var options =
{
oAuthUseToken : "always",
oAuthServiceName : 'fusiontables',
method : "POST",
payload : "sql=INSERT INTO {fusion id} ('Heading') VALUES ('ONE')",
contentType : "application/x-www-form-urlencoded"
};
var fetchResult = UrlFetchApp.fetch(oAuthFields.queryUrl, options);
return JSON.parse(fetchResult.getContentText());
}
对于上下文,googleAuth()函数和该函数的总体布局与我用于在融合表中添加列的函数相同(可以工作)。
文档有问题,缺少一些细节。
可以使用sql=…请求url中的参数。ContentType报头通常是application/json,但API也可能接受其他ContentTypes。在这种情况下,您的URL长度限制为2048个字符。
也可以使用sql=…POST主体中的。在这种情况下,你必须设置内容类型必须是application/x-www-form-urlencoded。1个请求中最多只能有500条INSERT语句。
另一个选择是使用importRows方法。这里您将使用CSV作为POST主体。在这种方法中,上传的数据限制为100MB。内容类型必须为"application/octet-stream"。注意:url与上面的不同:https://www.googleapis.com/upload/fusiontables/v1/tables/tableId/import。此外,如果您在正文中提供非UTF-8字符,则必须给出&encoding=… url参数更多细节在这里:importRows引用
成功!经过大量的研究,我解决了这个问题。这不是有效负载或内容类型问题(事实上,我发现.fetch自动默认为"application/x-www-form-urlencoded"编码)。问题出在授权上。我使用James Ferreira的聚变表库作为模型,并在我的代码和库的UrlFetchApp.fetch(url, fetchArgs).getContentText()
之前插入Logger.log(UrlFetchApp.getRequest(url, fetchArgs))
。
//log entry for library
{oAuthServiceName=fusion, useIntranet=false, followRedirects=true, oAuthUseToken=always, payload=sql=INSERT INTO 1b4kT_aYRfNBy8ZPtSZqhQUqVSVIYj_QWiBmjXXI ('Heading', 'Heading 2') VALUES ('NONE','TWO'), method=POST, validateHttpsCertificates=true, contentType=application/x-www-form-urlencoded, url=https://www.google.com/fusiontables/api/query}
//log entry for my code
{oAuthServiceName=fusiontables, useIntranet=false, followRedirects=true, oAuthUseToken=always, payload=sql=INSERT+INTO+1b4kT_aYRfNBy8ZPtSZqhQUqVSVIYj_QWiBmjXXI+('Heading',+'Heading+2')+VALUES+('NONE','TWO'), method=POST, validateHttpsCertificates=true, contentType=application/x-www-form-urlencoded, url=https://www.googleapis.com/fusiontables/v1/query}
然后,我比较了工作库的日志和我自己的日志,发现了三个不同之处。
- 我认为是编码sql语句的差异("INSERT INTO"vs。"插入+")。
- 请求的"service"参数不同("fusion"与"fusion")。"fusiontables")。
- qpi查询url不一致。(" www.google.com/fusiontables/api/query " vs。"www.googleapis.com/fusiontables/v1/query)。
经过一些实验,我确定…
- 假定编码与我的错误无关。
- 服务参数也不相关。我在各种文档中都看到过,其中任何一个似乎都有效。 令人沮丧的是,这就是问题所在。这是令人沮丧的,因为api文档说要使用一个不能工作。显然,www.googleapis.com/fusiontables/v1/query是用于OAuth2.0的。OAuthConfig(我在GAS中使用的内置授权工具)尚未迁移到2.0,因此缺少文档。我已经提交了一个迁移OAuthConfig的功能请求。如果你也想解决这个问题,请给这个帖子一些爱。