如何每月加载 data/update Power BI 数据集

How to load data/update Power BI Dataset monthly

我被要求实施一种每月一次将数据加载到我的数据集中的方法。由于 Power BI 服务没有此选项,我不得不使用 Power Query 找到解决方案,下面我将逐步描述我的解决方案。

如果对您有所帮助,请在下方发表评论让我知道。如果您有更好的 and/or 更优雅的解决方案,我很高兴收到您的来信。

解决方案

首先让我恢复解决方案。我只是在每个查询的末尾放置一个条件执行,以检查今天是否是必须上传新数据的日子。如果是,它 returns 要执行的步骤,如果不是,它会引发错误。 有很多方法可以实现它,我将从最简单的形式到更复杂的形式。

最简单的版本:检查是否是在查询中直接加载新数据的日子

这是实现该解决方案的最简单方法,但根据您的数据集,它可能不是最聪明的方法。

假设您有这个 foo 查询:

let
 step1 = ...,
 ...,
 ...,
 step10 = SomeFunction(Somevariable, someparameter)
in
 setp10

现在假设您希望该查询仅在每月的第一天上传新数据。为此,您只需在 in 子句中插入一个条件结构。

let
 step1 = ...,
 ...,
 ...,
 step10 = SomeFunction(Somevariable, someparameter)
in
 if Date.Day(DateTime.LocalNow()) = 1 then setp10 else error "Today is not the day to load data"

在这个例子中,我只是用这段代码替换了查询 return 处的 setp10if Date.Day(DateTime.LocalNow()) = 1 then setp10 else error "Today is not the day to load data"。通过这样做,setp10 将仅当此查询在该月的第一天执行时作为此查询的结果,否则,它将 return 一个错误。

这里值得解释一下。 Power Query 不是按照声明的相同顺序运行的脚本语言。因此,条件语句放在查询末尾的事实并不意味着上面的所有代码都将在错误启动之前执行。由于 Power Query 只执行必要的操作,因此 if... 语句可能是第一个被执行的语句。有关 Power Query 如何在幕后工作的更多信息,我强烈推荐您阅读:https://bengribaudo.com/blog/2018/02/28/4391/power-query-m-primer-part5-paradigm

使用函数

现在让我们继续前进。假设您的数据集不仅有一个,而且有很多查询,而且所有这些查询每月只需要执行一次。在这种情况下,一个聪明的方法是使用所有其他编程语言必须重用代码块:创建一个函数! 为此,创建一个新的空白查询并将此代码粘贴到其正文中:

(step) =>
let
  result = if Date.Day(DateTime.LocalNow()) = 1 then step else error "Today is not the day to load data"
in
  result

现在,在每次查询时,您将调用此函数,将最后一个 setp 作为参数发送。该函数将检查今天是哪一天,如果是加载数据的那一天,return 将作为参数传递相同的步骤。否则会出现return的错误。 下面是我们的查询代码,使用我们的函数 check_if_upload

let
 step1 = ...,
 ...,
 ...,
 step10 = SomeFunction(Somevariable, someparameter)
 step11 = check_if_upload(step10)
in
 step11

使用参数

最后一个提示。如果今天不是上传日,您的查询会引发错误,这意味着您每个月只能测试一次 ETL,对吗?该错误消息还限制您保存 Power Query,这意味着如果您不应用修改,则无法将新的 Power Query 版本(具有此实现)上传到 Power BI 服务。 好吧,您可以将日期验证的值更改为函数,但比方说,有点假。 更改此参数的更优雅的方法是使用参数。所以,让我们开始吧。创建一个参数(我称之为 Upload Day)作为数字类型。现在,您所要做的就是在您的函数中使用此参数。它看起来像这样:

(step) =>
let
  result = if Date.Day(DateTime.LocalNow()) = #"Upload Day" then step else error "Today is not the day to load data"
in
  result

就是这样。现在您可以直接在 Power BI 服务中更改上传日期,只需在数据集上更改此参数(单击数据集名称并转到设置 >> 参数)。

希望您对它有所帮助,希望它对您有所帮助。

此致。

因此,由于我的第一个解决方案没有用,在这里我将 post 我们(我和我的大学)找到的确定性解决方案。 不得不说,这个解决方案并不简单,它使用了Linux服务器,Gitlab和Jenkins,所以它需要一个相对复杂的环境,我不会描述如何构建它。

最后,我会提出一个更简单的解决方案。

环境

在我的公司,我们使用 Jenkins 来安排作业,Gitlab 来存储源代码,我们有一个 Linux 服务器来使用 Shell 脚本执行小任务。对于这个问题,我使用了除 Power BI 之外的所有三种服务 API.

詹金斯

我使用 Jenkins 来安排一项 运行 montlhy 的工作。此作业是使用以下配置创建的:

  • 参数:我创建了 2 个参数(workspace_id 和 dataset_id),因此我可以通过更改这些参数的值在任何环境(Power BI 工作区)中测试脚本;
  • 计划作业:此作业被安排在每天 1 运行 02:00 a.m。由于 Jenkins 使用与 CRON 相同的语法(我认为它只是你和 CRON 之间的中间值),该字段的值为 0 2 1 * *.
  • 构建:这里我们有一个远程 linux 服务器来执行脚本,我使用了 Execute shell script on remote host using ssh。我不知道为什么在 Jenkins 上你不能直接在作业上执行 curl 命令,它只是不起作用,所以我不得不将解决方案分成 Jenkins 和 Linux 服务器。在 SSH site 您必须 select 凭据(之前由我的团队创建)并且在 command 是以下命令:
#Navigate to the script shell directory
cd "script-shell-script/"

# pulls the last version of the script. If you aren't using Gitlab,
# remove this command
git pull

# every time git pulls a new file version, it has read access.
# This command allows the execution of the filechmod +x powerbi_refresh_dataset.sh

# make a call to the file passing as parameter the workspace id and dataset id
./powerbi_refresh_dataset.sh $ID_WORKSPACE $ID_DATASET

SHELL SCIPT

如你所想,核心解决方案是powerbi_refresh_dataset.sh的内容。但是,在开始之前,您必须了解 Power BI API 的工作原理,并且必须配置 Power BI 环境才能使 API 调用正常工作。因此,请确保您已经按照本教程正确配置了主要服务:https://docs.microsoft.com/en-us/power-bi/developer/embedded/embed-service-principal 获得 object_idclient_idclient_secret 后,您可以创建 shell 脚本文件。下面是我的 .sh 文件的代码。

# load OBJECT_ID, CLIENT_ID and CLIENT_SECRET as environment variables
source credential_file.sh

# This command retrieves a new token from Microsoft Credentials Manager
token_msg=$(curl -X POST "https://login.windows.net/$OBJECT_ID/oauth2/token" \
   -H 'Content-Type: application/x-www-form-urlencoded' \
   -H 'Accept: application/json' \
   -d 'grant_type=client_credentials&resource=https://analysis.windows.net/powerbi/api&client_id='$CLIENT_ID'&client_secret='$CLIENT_SECRET
   )
# Extract the token from the response message
token=$(echo "$token_msg" | jq -r '.access_token')

# Ask Power BI to refresh dataset
refresh_msg=$(curl -X POST 'https://api.powerbi.com/v1.0/myorg/groups/''/datasets/''/refreshes' \
-H 'Authorization: Bearer '$token \
-H 'Content-Type: application/json' \
-d '{"notifyOption": "NoNotification"}')

这里有一些解释。第一个命令是 source credential_file.sh,它加载 3 个变量(OBJECT_ID、CLIENT_ID 和 CLIENT_SECRET)。此处的目的是将机密信息与脚本分开,以便我可以将主脚本文件存储在版本控制 (Git) 上,而不泄露任何敏感信息。因此,除了 powerbi_refresh_dataset.sh 文件外,您还必须在同一目录中包含 credential_file.sh 并包含以下内容:

OBJECT_ID=OBJECT_ID_VALUE CLIENT_ID=CLIENT_ID_VALUE CLIENT_SECRET=CLIENT_SECRET_VALUE

重要的是要说明,如果您使用 Git 或任何其他版本控制,只有 powerbi_refresh_dataset.sh 文件进入版本控制并且 credential_file.sh 文件必须仅保留在您的 Linux 服务器。我建议您将其内容保存到密码存储应用程序中,例如 keepass,因为 CLIENT_SECRET 无法检索。

最终考虑

以上是我的解决方案最相关的信息。如您所见,我(有意地)忽略了如何构建环境并让他们交谈(使用 linux 的 jekins、使用 Git 的 jenkins 等等)。 如果您只有 Linux 或 Windows 主机,我建议您这样做:

Linux主机

在这个更简单的环境中,只需创建 powerbi_refresh_dataset.shcredential_file.sh,将其放在任何目录并创建一个 CRON 任务以根据需要多次调用 powerbi_refresh_dataset

Windows主机

在 windows 上你可以做几乎和在 Linux 上一样的事情,但是你必须用 Power Shell 命令替换 shell 脚本文件的内容(google 它)并使用 Scheduled Task 定期执行你的 Power Shell 文件。

好吧,我想这会对你有所帮助。我知道这不是一个完整的答案,因为它只有在您有类似的环境时才有效,但我希望最后的提示可能对您有所帮助。

此致