diff --git a/metabase.py b/metabase.py index c3a0d1b..156afda 100644 --- a/metabase.py +++ b/metabase.py @@ -346,10 +346,11 @@ def get_dashboards(self, database_name): for d in dashbords_light: res = self.query('GET', 'dashboard/'+str(d['id'])) good_db = True - for c in res['ordered_cards']: - if c['card'].get('database_id') and c['card'].get('database_id') != database_id: - good_db = False - continue + if 'dashcards' in res: + for c in res['dashcards']: + if c['card'].get('database_id') and c['card'].get('database_id') != database_id: + good_db = False + continue if not good_db: continue dashboards.append(res) @@ -586,7 +587,7 @@ def convert_ids2names(self, database_name, obj, previous_key): def export_dashboards_to_json(self, database_name, dirname): export = self.get_dashboards(database_name) for dash in export: - if len(dash['ordered_cards']): + if len(dash['dashcards']): dash = self.clean_object(dash) with open(dirname+"/dashboard_"+dash['name'].replace('/', '')+".json", 'w', newline = '') as jsonfile: jsonfile.write(json.dumps(self.convert_ids2names(database_name, dash, None))) @@ -604,9 +605,11 @@ def clean_object(self, object): del object['last-edit-info'] if 'result_metadata' in object and object['result_metadata']: for i in range(0, len(object['result_metadata'])): - del object['result_metadata'][i]['fingerprint'] - if 'ordered_cards' in object: - for c in object['ordered_cards']: + if 'fingerprint' in object['result_metadata'][i]: + del object['result_metadata'][i]['fingerprint'] + if 'dashcards' in object: + for c in object['dashcards']: + del c['card'] c = self.clean_object(c) if 'card' in object: object['card'] = self.clean_object(object['card']) @@ -676,21 +679,6 @@ def metric_import(self, database_name, metric_from_json): self.metrics_name2id = {} return self.query('POST', 'metric', metric_from_json) - def dashboard_delete_all_cards(self, database_name, dashboard_name): - dash = self.get_dashboard(database_name, dashboard_name) - res = [] - for c in dash['ordered_cards']: - res.append(self.query('DELETE', 'dashboard/'+str(dash['id'])+'/cards?dashcardId='+str(c['id']))) - return res - - def dashboard_import_card(self, database_name, dashboard_name, ordered_card_from_json): - dashid = self.dashboard_name2id(database_name, dashboard_name) - cardid = ordered_card_from_json.get('card_id') - if cardid: - ordered_card_from_json['cardId'] = cardid - ordered_card_from_json.pop('card') - return self.query('POST', 'dashboard/'+str(dashid)+'/cards', ordered_card_from_json) - def import_snippets_from_json(self, database_name, dirname, collection_name = None): res = [] jsondata = self.get_json_data('snippet_', dirname) @@ -713,12 +701,10 @@ def import_snippets_from_json(self, database_name, dirname, collection_name = No def import_cards_from_json(self, database_name, dirname, collection_name = None): res = [] jsondata = self.get_json_data('card_', dirname) - for dash in self.get_json_data('dashboard_', dirname): - for embed_card in dash['ordered_cards']: - if embed_card and embed_card['card']: - jsondata.append(embed_card['card']) if len(jsondata): errors = None + # sort cards to put models first + jsondata.sort(key=lambda card: card['type'] != 'model') for card in jsondata: try: res.append(self.card_import(database_name, self.convert_names2ids(database_name, collection_name, card))) @@ -765,15 +751,22 @@ def import_metrics_from_json(self, database_name, dirname, collection_name = Non return res def import_dashboards_from_json(self, database_name, dirname, collection_name = None): - res = [[], [], []] + res = [[], []] jsondata = self.get_json_data('dashboard_', dirname) if len(jsondata): jsondata = self.convert_names2ids(database_name, collection_name, jsondata) for dash in jsondata: - res[0].append(self.dashboard_import(database_name, dash)) - self.dashboard_delete_all_cards(database_name, dash['name']) - for ocard in dash['ordered_cards']: - res[1].append(self.dashboard_import_card(database_name, dash['name'], ocard)) + # Create or update dashboard with no cards + empty_cards=dash.copy() + empty_cards['dashcards'] = [] + res[0].append(self.dashboard_import(database_name, empty_cards)) + + # Update dashboard with cards (and negative id) + i=1 + for ocard in dash['dashcards']: + ocard['id'] = -i + i += 1 + res[1].append(self.dashboard_import(database_name, dash)) return res def get_users(self): diff --git a/metabase_import.py b/metabase_import.py index e184a17..0926a22 100644 --- a/metabase_import.py +++ b/metabase_import.py @@ -6,12 +6,13 @@ metabase_password = sys.argv[3] metabase_base = sys.argv[4] metabase_exportdir = sys.argv[5] +metabase_collection = sys.argv[6] ametabase = metabase.MetabaseApi(metabase_apiurl, metabase_username, metabase_password) #ametabase.debug = True ametabase.import_fields_from_csv(metabase_base, metabase_exportdir) ametabase.sync_scan_database(metabase_base) -ametabase.import_metrics_from_json(metabase_base, metabase_exportdir) -ametabase.import_cards_from_json(metabase_base, metabase_exportdir) -ametabase.import_dashboards_from_json(metabase_base, metabase_exportdir) +ametabase.import_metrics_from_json(metabase_base, metabase_exportdir, metabase_collection) +ametabase.import_cards_from_json(metabase_base, metabase_exportdir, metabase_collection) +ametabase.import_dashboards_from_json(metabase_base, metabase_exportdir, metabase_collection)