使用Power Bi 可以在組織內(nèi)便捷地共享數(shù)據(jù)集带族。在發(fā)布了一份數(shù)據(jù)集之后,你可以輕易地基于該數(shù)據(jù)集創(chuàng)建一份新的報表:
今年此蜈,我就在一個二期項目中將該公司所有五十多個報表文件統(tǒng)一連接到同一個中央模型上,幾乎是把PowerBi用成了SSAS。這樣做的好處是大大減輕了模型維護(hù)的工作量腰奋。在過去,業(yè)務(wù)邏輯稍有變動抱怔,動輒要跟著修改十幾張報表劣坊,體力活極多。而現(xiàn)在屈留,我只需要付出很小的工作量即可統(tǒng)一修改五十多張報表中的業(yè)務(wù)邏輯局冰、配色等。
便捷的同時灌危,也帶來了一個新問題:當(dāng)我想將這種基于云端數(shù)據(jù)集創(chuàng)建的報表遷移到其它組織(比如锐想,該公司的BI測試環(huán)境)時,遇到了很大麻煩乍狐。并不是想象中的換個賬號切換數(shù)據(jù)源那么簡單赠摇。接下來的文字中,我會把這個問題稱為“無權(quán)限宕機(jī)問題”浅蚪。
如果公司安全流程不是很嚴(yán)格藕帜,測試環(huán)境的賬號與生產(chǎn)環(huán)境賬號在同一組織中(或者購買了PowerBiPremium以跨組織共享數(shù)據(jù)集),并且可以將生產(chǎn)環(huán)境的數(shù)據(jù)集授權(quán)給測試賬號惜傲,那么不會遇到這個所謂的“無權(quán)限宕機(jī)問題”洽故。
這個問題的具體表現(xiàn)是:對于使用組織A賬號基于云端數(shù)據(jù)集創(chuàng)建的報表,無法使用組織B賬號打開盗誊。
如果你嘗試這樣做并且期望打開后將數(shù)據(jù)源更改為組織B中的相同結(jié)構(gòu)的云端數(shù)據(jù)集时甚,你會看到這個:
點擊重試顯然不會起任何作用;點擊編輯看起來像是會強行打開報表并允許更改該報表的數(shù)據(jù)源(至少在我點擊之前是這么猜測的)哈踱,但事實是荒适,點擊了編輯之后,你會看到你的PowerBIDesktop死機(jī)了……
手動解決方案
經(jīng)過探索开镣,我發(fā)現(xiàn)決定了數(shù)據(jù)集引用的是報表文件解包后的Connections文件刀诬。因此,要想解決這個問題邪财,只需要以下步驟:
- 從組織B的云端數(shù)據(jù)集創(chuàng)建報表樣例B.pbix
- 將B.pbix改后綴得到B.pbix.zip
- 打開B.pbix.zip陕壹,提取出根目錄下的Connections文件
- 將待轉(zhuǎn)換的A組織報表anyReportA.pbix重命名為anyReportB.pbix.zip
- 打開anyReportB.pbix.zip质欲,使用之前提取出的B組織的Connections文件覆蓋
- 重命名anyReportB.pbix.zip為anyReportB.pbix
這樣,我們就順利地將A組織中基于云端數(shù)據(jù)集創(chuàng)建的報表anyReportA.pbix遷移到了B組織中糠馆,使用登陸了B組織賬號的Power BI Desktop可以正常編輯嘶伟、發(fā)布anyReportB.pbix。
自動化
考慮到源報表更新時可能需要同步更新另一個組織的報表又碌,可以將解決方案自動化奋早。
main.py:
from zipfile import ZipFile
import os
from shutil import make_archive,rmtree
from config import report_pairs
def replace(report_file_name:str,dataset_example_file_name:str):
'''
report_file_name: 等待更換的報表文件
dataset_example_file_name: 要更換到的目標(biāo)數(shù)據(jù)集
'''
with ZipFile(file=dataset_example_file_name,mode='r') as new_dataset_pbix:
new_dataset_connection = new_dataset_pbix.read(name='Connections').decode('utf-8')
# 解壓
with ZipFile(file=report_file_name,mode='r') as file_mati:
file_path=os.path.dirname(report_file_name)
temp_dir=os.path.join(file_path,'.temp')
temp_extract_dir=os.path.join(temp_dir,os.path.basename(report_file_name))
file_mati.extractall(path=temp_extract_dir)
# 替換connections文件
with open(os.path.join(temp_extract_dir,'connections'),mode='w') as temp_connections_file:
temp_connections_file.write(new_dataset_connection)
make_archive(report_file_name,root_dir=temp_extract_dir,format='zip')
# 清空.temp文件
rmtree(temp_dir)
# 刪除報表文件
os.remove(report_file_name)
# 將打包好的新報表文件重命名
os.rename(report_file_name+'.zip',report_file_name)
if __name__=='__main__':
for row in report_pairs.iterrows():
replace(report_file_name=row[1]['報表文件'],dataset_example_file_name=row[1]['數(shù)據(jù)源'])
config.py:
import pandas as pd
df=pd.read_excel('config-dev.xlsx')
report_pairs=df
if __name__=='__main__':
print(report_pairs)