Это зависит от типа источника данных (SQL Server, SSAS, CSV-файлы и т. Д.) И режима подключения к данным (импорт, прямой запрос и т. Д.). Если вы можете использовать параметры, то один из вариантов - разрешить вновь клонированному отчету самостоятельно переключать свой источник данных, используя параметры подключения . Для этого откройте Power Query Editor
, нажав Edit Queries
и в Manage Parameters
определите два новых текстовых параметра, назовите их ServerName
и DatabaseName
:
Установите их текущие значения так, чтобы они указывали на один из ваших источников данных, например, SQLSERVER2016
и AdventureWorks2016
. Затем щелкните правой кнопкой мыши ваш запрос в отчете и откройте Advanced Editor
. Найдите имя сервера и имя базы данных в M-коде:
и замените их параметрами, определенными выше, так что M-код будет выглядеть следующим образом:
Теперь вы можете закрывать и применять изменения, и ваш отчет должен работать как прежде. Но теперь, когда вы хотите изменить источник данных, сделайте это, используя Edit Parameters
:
и измените имя сервера и / или базы данных на точкук другому источнику данных, который вы хотите использовать для отчета:
После изменения значений параметров Power BI Desktop попросит вас применитьизменения и перезагрузите данные из нового источника данных. Чтобы изменить значения параметров (т. Е. Источник данных) отчета, опубликованного в Power BI Service, перейдите в настройки набора данных и введите имя нового сервера и / или базы данных (проверьте также настройки шлюза, если это локальный источник данных):
После изменения источника данных обновите набор данных, чтобы получить данные из нового источника данных. С учетной записью Power BI Pro вы можете делать это 8 раз в сутки, в то время как если набор данных находится в выделенной емкости, этот предел увеличивается до 48 раз в сутки.
Чтобы сделать это программно, используйте Update Parameters
/ Update Parameters In Group
и Refresh Dataset
/ Refresh Dataset In Group
вызовы API REST. Например, вы можете сделать это с помощью PowerShell следующим образом:
Import-Module MicrosoftPowerBIMgmt
Import-Module MicrosoftPowerBIMgmt.Profile
$password = "xxxxx" | ConvertTo-SecureString -asPlainText -Force
$username = "xxxxx@yyyyy.com"
$credential = New-Object System.Management.Automation.PSCredential($username, $password)
Connect-PowerBIServiceAccount -Credential $credential
Invoke-PowerBIRestMethod -Url 'groups/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/datasets/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/UpdateParameters' -Method Post -Body '{
"updateDetails": [
{
"name": "ServerName",
"newValue": "SQLSERVER2019"
},
{
"name": "DatabaseName",
"newValue": "AdventureWorks2019"
}
]
}'
Invoke-PowerBIRestMethod -Url 'groups/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/datasets/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/refreshes' -Method Post
Disconnect-PowerBIServiceAccount
Если вы не можете использовать параметры, например, прямое подключение к SSAS, строку подключения можно изменить с помощью Обновить источники данных в группе вызов API REST. В PowerShell это можно сделать следующим образом:
Import-Module MicrosoftPowerBIMgmt
Import-Module MicrosoftPowerBIMgmt.Profile
$password = "xxxxx" | ConvertTo-SecureString -asPlainText -Force
$username = "xxxxx@yyyyy.com"
$credential = New-Object System.Management.Automation.PSCredential($username, $password)
Connect-PowerBIServiceAccount -Credential $credential
Invoke-PowerBIRestMethod -Url 'groups/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/datasets/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Default.UpdateDatasources' -Method Post -Body '{
"updateDetails": [
{
"datasourceSelector": {
"datasourceType": "AnalysisServices",
"connectionDetails": {
"server": "My-As-Server",
"database": "My-As-Database"
}
},
"connectionDetails": {
"server": "New-As-Server",
"database": "New-As-Database"
}
}
]
}'
Disconnect-PowerBIServiceAccount
Обратите внимание, что вам необходимо предоставить как старые, так и новые имена серверов и баз данных.
В C # вы можете сделать то же самое в оченьАналогично, даже без клиента Power BI:
var group_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
var dataset_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
var restUrlUpdateParameters = $"https://api.powerbi.com/v1.0/myorg/groups/{group_id}/datasets/{dataset_id}/Default.UpdateParameters";
var postData = new { updateDetails = new[] { new { name = "ServerName", newValue = "NEWSERVER" }, new { name = "DatabaseName", newValue = "Another_AdventureWorks2016" } } };
var responseUpdate = client.PostAsync(restUrlUpdateParameters, new StringContent(JsonConvert.SerializeObject(postData), Encoding.UTF8, "application/json")).Result;
var restUrlRefreshDataset = $"https://api.powerbi.com/v1.0/myorg/groups/{group_id}/datasets/{dataset_id}/refreshes";
var responseRefresh = client.PostAsync(restUrlRefreshDataset, null).Result;
Использование клиента Power BI C # может облегчить вам жизнь, например, обновление отчета может быть выполнено следующим образом:
var group_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
var dataset_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
var credentials = new TokenCredentials(accessToken, "Bearer");
using (var client = new PowerBIClient(new Uri("https://api.powerbi.com"), credentials))
{
client.Datasets.RefreshDatasetInGroup(group_id, dataset_id);
}
КогдаДля вызова API необходимо предоставить токен доступа. Чтобы приобрести его, используйте библиотеки ADAL или MSAL , например, с таким кодом:
private static string resourceUri = "https://analysis.windows.net/powerbi/api";
private static string authorityUri = "https://login.windows.net/common/"; // It was https://login.windows.net/common/oauth2/authorize in prior versions
private static string clientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; // Register at https://dev.powerbi.com/apps
private static string groupId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
private static string reportId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
private static AuthenticationContext authContext = new AuthenticationContext(authorityUri, new TokenCache());
public string Authenticate()
{
AuthenticationResult authenticationResult = null;
// First check is there token in the cache
try
{
authenticationResult = authContext.AcquireTokenSilentAsync(resourceUri, clientId).Result;
}
catch (AggregateException ex)
{
AdalException ex2 = ex.InnerException as AdalException;
if ((ex2 == null) || (ex2 != null && ex2.ErrorCode != "failed_to_acquire_token_silently"))
{
MessageBox.Show(ex.Message);
return;
}
}
if (authenticationResult == null)
{
var uc = new UserPasswordCredential("user@example.com, "Strong password");
try
{
authenticationResult = authContext.AcquireTokenAsync(resourceUri, clientId, uc).Result;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + ex.InnerException == null ? "" : Environment.NewLine + ex.InnerException.Message);
return;
}
}
if (authenticationResult == null)
MessageBox.Show("Call failed.");
else
{
return authenticationResult.AccessToken;
}
}