一如既往 - 非常感谢社区的帮助。
以下是我调用 API initReq 的代码,如果该 API 不为 null,则转到 Gatherpagingdata。 Gatherpagingdata 使用会更改的 URL,并从 uri = initReq[pageDetails][nextPageUrl] 收集,然后在 Gatherpagingdata 函数 nextPageUrl = newReq[pageDetails][nextPageUrl] 中收集。我已经检查了 uri 作为文本,标题都作为文本传递,我还检查了 nextpagefunc、textBeforePaging 和 textAfterPaging 尽可能作为文本传递,因为它们然后在 newReq = Json.Document(Web.Contents) 中使用(textBeforePaging, [Headers=headers, Query=[paging=textAfterPaging]])).
考虑到这一点,我不明白为什么这无法正常工作,并且是下面错误的根源。
我有一种感觉,当我尝试在函数中运行非动态 URL 时,这将是我没有考虑到的事情,因为它似乎可以在函数中实现。
如果您提供任何帮助,我们将不胜感激。
T
let
// NB Making calls to multiple instances from the same Power BI Dash can cause problems with authentication
// https://www.youtube.com/watch?v=fstsQMZiHME
// check data source security
// Common parameters
queryStringApiIntegrationCodevar = "xxxxxx",
queryStringUserNamevar = "xxxxxxxxx",
queryStringUserSecretvar = "xxxxxxxx",
queryStringContentTypevar = "application/json",
headers = [
#"ApiIntegrationCode"=queryStringApiIntegrationCodevar,
#"UserName"=queryStringUserNamevar,
#"Secret"=queryStringUserSecretvar,
#"Content-Type"=queryStringContentTypevar
],
apiUrl = "https://webservices4.autotask.net/ATServicesRest/V1.0/Projects/query",
apiUrlnew = "https://webservices4.autotask.net/ATServicesRest/V1.0/Projects/query/next",
searchFilter = "{""filter"":[{""op"":""gte"",""field"":""id"",""value"":""0""}]}",
// Functions
converturl = (data as text) as text =>
let
out = Uri.Parts("http://contoso?a=" & Text.Replace(data, "&", "%26"))[Query][a]
in
out,
gatherpagingdata = (data as list, uri as text, headers) =>
let
// Get the Data
// Replace Percent URL-encoded characters
nextpagefunc = converturl(uri) as text,
textBeforePaging = Text.BeforeDelimiter(nextpagefunc, "?paging=") as text,
textAfterPaging = Text.BetweenDelimiters(nextpagefunc, "?paging=", " ") as text,
newReq = Json.Document(Web.Contents(textBeforePaging, [Headers=headers, Query=[paging=textAfterPaging]])),
newdata = newReq[items],
// Add that data to rolling aggregate
updatedData = List.Combine({data, newdata}),
// Check for the next URL using function
nextPageUrl = newReq[pageDetails][nextPageUrl],
// If there's no next page of data, return. If there is, call @gatherpagingdata again to get more data
result = if nextPageUrl <> null then @gatherpagingdata(updatedData, nextPageUrl, headers) else updatedData
in
result,
// Execute
initReq = try Json.Document(Web.Contents(apiUrl, [Headers=headers, Query=[search=searchFilter]])) otherwise error "Failed to retrieve data from the API 1st Pass",
initData = initReq[items],
// Before we call gather(), we want to see if it's even necessary.
// First request returns only one page? Return.
// OutputList = try if initReq[pageDetails][nextPageUrl] = null then initData else gather(initData, BaseURI) otherwise error uri,
uri = initReq[pageDetails][nextPageUrl],
// Decode the extracted value
// Replace Percent URL-encoded characters
nextpagefunc = converturl(uri),
outputList =
if initReq[pageDetails][nextPageUrl] = null then
initData
else
gatherpagingdata(initData, uri, headers),
// Then place records into a table. This will expand all columns available in the record.
expand = Table.FromRecords(outputList)
in
expand
错误:
DataSource.Error:Web.Contents 无法从中获取内容 'https://webservices4.autotask.net/ATServicesRest/V1.0/Projects/query/next?paging=%7B%22pageSize%22%3A500%2C%22previousIds%22%3A%5B3%5D%2C%22nextIds% 22%3A%5B593%5D%7D%26search%3D%7B%22filter%22%3A%5B%7B%22op%22%3A%22gte%22%2C%22field%22%3A%22id%22%2C% 22值%22%3A%220%22%7D%5D%7D' (405):不允许的方法详细信息: 数据源种类=Web DataSourcePath=https://webservices4.autotask.net/ATServicesRest/V1.0/Projects/query/next 网址=https://webservices4.autotask.net/ATServicesRest/V1.0/Projects/query/next?paging=%7B%22pageSize%22%3A500%2C%22previousIds%22%3A%5B3%5D%2C%22nextIds %22%3A%5B593%5D%7D%26search%3D%7B%22filter%22%3A%5B%7B%22op%22%3A%22gte%22%2C%22field%22%3A%22id%22%2C %22值%22%3A%220%22%7D%5D%7D
工作代码:
let
// NB Making calls to multiple instances from the same Power BI Dash can cause problems with authentication
// https://www.youtube.com/watch?v=fstsQMZiHME
// check data source security
// Common parameters
queryStringApiIntegrationCodevar = "xxxxx",
queryStringUserNamevar = "xxxxx",
queryStringUserSecretvar = "xxxxx",
queryStringContentTypevar = "application/json",
headers = [
#"ApiIntegrationCode"=queryStringApiIntegrationCodevar,
#"UserName"=queryStringUserNamevar,
#"Secret"=queryStringUserSecretvar,
#"Content-Type"=queryStringContentTypevar
],
apiUrl = "https://webservices4.autotask.net/ATServicesRest/V1.0/Projects/query",
apiUrlnew = "https://webservices4.autotask.net/ATServicesRest/V1.0/Projects/query/next",
searchFilter = "{""filter"":[{""op"":""gte"",""field"":""id"",""value"":""0""}]}",
// Functions
converturl = (data as text) as text =>
let
out = Uri.Parts("http://contoso?a=" & Text.Replace(data, "&", "%26"))[Query][a]
in
out,
gatherpagingdata = (data as list, uri as text, headers, searchFilter) =>
let
// Get the Data
// Replace Percent URL-encoded characters
nextpagefunc = converturl(uri) as text,
textBeforePaging = Text.BeforeDelimiter(nextpagefunc, "?paging=") as text,
textAfterPagingandBeforesearch = Text.BetweenDelimiters(nextpagefunc, "?paging=", "&search=") as text,
textAfterPagingandsearchEquals = Text.BetweenDelimiters(nextpagefunc, "&search=", " ") as text,
// pull out search filter
newReq = Json.Document(Web.Contents(textBeforePaging, [Headers=headers, Query=[paging=textAfterPagingandBeforesearch , search=textAfterPagingandsearchEquals]])),
newdata = newReq[items],
// Add that data to rolling aggregate
updatedData = List.Combine({data, newdata}),
// Check for the next URL using function
nextPageUrl = newReq[pageDetails][nextPageUrl],
// If there's no next page of data, return. If there is, call @gatherpagingdata again to get more data
result = if nextPageUrl <> null then @gatherpagingdata(updatedData, nextPageUrl, headers , searchFilter) else updatedData
in
result,
// Execute
apiUrltest = "https://webservices4.autotask.net/ATServicesRest/V1.0/Projects/query/next",
searchFiltertest = "{""pageSize"":500,""previousIds"":[3],""nextIds"":[593]}",
searchFiltertest2 = "{""filter"":[{""op"":""gte"",""field"":""id"",""value"":""0""}]}",
//initReq = try Json.Document(Web.Contents(apiUrl, [Headers=headers, Query=[search=searchFilter]])) otherwise error "Failed to retrieve data from the API 1st Pass",
initReq = try Json.Document(Web.Contents(apiUrltest, [Headers=headers, Query=[paging=searchFiltertest, search=searchFilter ]])) otherwise error "Failed to retrieve data from the API 1st Pass",
initData = initReq[items],
// Before we call gather(), we want to see if it's even necessary.
// First request returns only one page? Return.
// OutputList = try if initReq[pageDetails][nextPageUrl] = null then initData else gather(initData, BaseURI) otherwise error uri,
uri = initReq[pageDetails][nextPageUrl],
// Decode the extracted value
// Replace Percent URL-encoded characters
nextpagefunc = converturl(uri),
outputList =
if initReq[pageDetails][nextPageUrl] = null then
initData
else
gatherpagingdata(initData, uri, headers , searchFilter),
// Then place records into a table. This will expand all columns available in the record.
expand = Table.FromRecords(outputList)
in
expand
发现问题...我不得不拆分并重新发送,而不是一次性发送整个查询字符串。
错误是因为显示 URL 正确,但实际上未正确处理。
更新了第一篇文章的代码。
谢谢大家