【问题标题】:Character string truncated when passed to function传递给函数时字符串被截断
【发布时间】:2018-03-01 22:16:13
【问题描述】:

我有一个很长的广告系列名称列表,我需要将其折叠为长度为 1 的字符向量,然后在通过“RAdwords”包调用 Google AdWords API 时作为“where”子句传递。

创建此字符串不是问题,直到它的长度达到某个值被截断的点,这会导致 AdWords API 调用出错。

这是一个不会导致错误的设置示例:

campaigns <- paste0("Campaign ", seq(1,5))
collapsed_campaigns <- paste0(campaigns, collapse = "','")
campaign_filter1 <- paste("CampaignName IN ['", collapsed_campaigns, "']")

这是一个会导致错误的设置:

campaigns <- paste0("Campaign ", seq(1,50))
collapsed_campaigns <- paste0(campaigns, collapse = "','")
campaign_filter2 <- paste("CampaignName IN ['", collapsed_campaigns, "']")

检查每个变量的结构显示:

> str(campaign_filter1)
 chr "CampaignName IN [' Campaign 1','Campaign 2','Campaign 3',
 'Campaign 4','Campaign 5 ']"
> str(campaign_filter2)
 chr "CampaignName IN [' Campaign 1','Campaign 2','Campaign 3',
 'Campaign 4','Campaign 5','Campaign 6','Campaign 7','Campaign 8','Camp"| __truncated__

如果我将 'campaign_filter1' 作为我在 RAdwords 中的 where 子句传递,事情会按预期运行。

如果我将“campaign_filter2”作为 where 子句传递,我会收到以下错误:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><reportDownloadError>
 <ApiError><type>QueryError.INVALID_WHERE_CLAUSE</type><trigger></trigger>
 <fieldPath></fieldPath></ApiError></reportDownloadError>

似乎“| truncated”正按字面意思传递给 RAdwords 函数。

这是在对 RAdwords 的失败调用中检查“traffic_data”结构的结果:

> str(traffic_data)
 Classes ‘data.table’ and 'data.frame': 1 obs. of  1 variable:
 $ ads: chr "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>
 <reportDownloadError><ApiError><type>QueryError.INVALID_WHERE_CLAU"| __truncated__
 - attr(*, ".internal.selfref")=<externalptr> 

显然,我可以绕过这种某种循环函数,并一次调用 API 中的数据一个活动,但这会非常低效。如何获取要传递给 RAdwords 的整个字符串?

【问题讨论】:

  • 您是否 100% 确定 | truncated 最终会出现在您的查询中?您是否检查过发送并验证的实际查询文本?我只是问,因为我会觉得这很令人惊讶。无论如何,检查实际的查询文本将是有益的,因为它会揭示具体的语法错误。
  • ...例如,当我运行RAdwords::statement 并仅提供您的长 WHERE 子句时,整个内容被清楚地插入,而不是截断。也许 API 对长度有限制...?
  • 啊,是的,我现在可以看到了。因此,答案将是,我必须找出 API 限制是什么并从那里解决它。谢谢!

标签: r character string-length


【解决方案1】:

前面有一个问题:为什么不下载所有广告系列数据并在 R 中过滤结果数据框?使用这种策略,整个字符串广告系列名称粘贴过程将变得多余。您可以根据 R 中的向量操作过滤数据帧。这种方法可能更可靠且不易受攻击。

但是,如果您想在 API 调用中明确过滤广告系列,您可以使用以下代码:

# 1. Download all campaigns
# query all campaign names
body1 <- statement(select=c('CampaignName'),
                  report="CAMPAIGN_PERFORMANCE_REPORT",
                  start="2017-11-01",
                  end="2017-11-02")
# download all campaign names
campaigns <- getData(clientCustomerId = "***-***-****",
                      google_auth = google_auth,
                      statement = body,
                      apiVersion = "201710",
                      transformation = T,
                      changeNames = T)
# 2. Build query with all campaigns in where clause
# build string for where clause
cmp_string <- paste0(campaigns$Campaign, collapse = "','")
cmp_string <- paste("CampaignName IN ['", cmp_string, "']", sep = "")
# query all campaigns with where condition
body2 <- statement(select = c('CampaignName'),
                  where = cmp_string,
                  report = "CAMPAIGN_PERFORMANCE_REPORT",
                  start = "2017-11-01",
                  end = "2017-11-02")
# download all campaigns using the where clause
campaigns2 <- getData(clientCustomerId = "***-***-****",
                     google_auth = google_auth,
                     statement = body,
                     apiVersion = "201710",
                     transformation = T,
                     changeNames = T)

在第一部分中,我下载了所有广告系列名称以获取 where 子句的数据。在第二部分中,我将演示如何使用 where 子句将所有广告系列作为过滤器再次下载所有广告系列。

我用 200 多个广告系列测试了上面的代码。 RAdwords 包和 Adwords API 都没有任何问题。

我怀疑您传递给campaign_filter2 的字符串存在问题。在paste() 中,您错过了设置sep = ""。否则,您最终会在第一个广告系列名称的开头出现一个空格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-14
    • 2011-06-05
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    相关资源
    最近更新 更多