Backup
This commit is contained in:
@@ -2,7 +2,7 @@ from superset_tool.models import SupersetConfig
|
|||||||
from superset_tool.client import SupersetClient
|
from superset_tool.client import SupersetClient
|
||||||
from superset_tool.utils.logger import SupersetLogger
|
from superset_tool.utils.logger import SupersetLogger
|
||||||
from superset_tool.exceptions import AuthenticationError
|
from superset_tool.exceptions import AuthenticationError
|
||||||
from superset_tool.utils.fileio import save_and_unpack_dashboard, update_db_yaml, create_dashboard_export
|
from superset_tool.utils.fileio import save_and_unpack_dashboard, update_db_yaml, create_dashboard_export, create_temp_file
|
||||||
import os
|
import os
|
||||||
import keyring
|
import keyring
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -21,9 +21,9 @@ database_config_click={"new":
|
|||||||
"sqlalchemy_uri": "clickhousedb+connect://clicketl:XXXXXXXXXX@rgm-s-khclk.hq.root.ad:443/dm",
|
"sqlalchemy_uri": "clickhousedb+connect://clicketl:XXXXXXXXXX@rgm-s-khclk.hq.root.ad:443/dm",
|
||||||
"uuid": "b9b67cb5-9874-4dc6-87bd-354fc33be6f9",
|
"uuid": "b9b67cb5-9874-4dc6-87bd-354fc33be6f9",
|
||||||
"database_uuid": "b9b67cb5-9874-4dc6-87bd-354fc33be6f9",
|
"database_uuid": "b9b67cb5-9874-4dc6-87bd-354fc33be6f9",
|
||||||
"allow_ctas": "true",
|
"allow_ctas": "false",
|
||||||
"allow_cvas": "true",
|
"allow_cvas": "false",
|
||||||
"allow_dml": "true"
|
"allow_dml": "false"
|
||||||
},
|
},
|
||||||
"old": {
|
"old": {
|
||||||
"database_name": "Dev Clickhouse",
|
"database_name": "Dev Clickhouse",
|
||||||
@@ -105,32 +105,36 @@ prod_client = SupersetClient(prod_config)
|
|||||||
from_c = dev_client
|
from_c = dev_client
|
||||||
to_c = sandbox_client
|
to_c = sandbox_client
|
||||||
dashboard_slug = "FI0050"
|
dashboard_slug = "FI0050"
|
||||||
#dashboard_id = 53
|
dashboard_id = 53
|
||||||
|
|
||||||
dashboard_meta = from_c.get_dashboard(dashboard_slug)
|
dashboard_meta = from_c.get_dashboard(dashboard_slug)
|
||||||
#print(dashboard_meta)
|
#print(dashboard_meta)
|
||||||
print(dashboard_meta["dashboard_title"])
|
#print(dashboard_meta["dashboard_title"])
|
||||||
|
|
||||||
dashboard_id = dashboard_meta["id"]
|
dashboard_id = dashboard_meta["id"]
|
||||||
zip_content, filename = from_c.export_dashboard(dashboard_id, logger=logger)
|
|
||||||
superset_repo = Path("H:\\dev\\dashboards\\")
|
|
||||||
# print(f"Экспортируем дашборд ID = {dashboard_id}...")
|
|
||||||
# #Сохранение и распаковка
|
|
||||||
zip_path, unpacked_path = save_and_unpack_dashboard(
|
|
||||||
zip_content=zip_content,
|
|
||||||
original_filename=filename,
|
|
||||||
unpack=True,
|
|
||||||
logger=logger,
|
|
||||||
output_dir=os.path.join(superset_repo,dashboard_slug)
|
|
||||||
)
|
|
||||||
dest_path = os.path.join(superset_repo,dashboard_slug)
|
|
||||||
source_path = os.path.join(unpacked_path,Path(filename).stem)
|
|
||||||
|
|
||||||
update_db_yaml(database_config_click, path = source_path, logger=logger)
|
with create_temp_file(suffix='.dir', logger=logger) as temp_root:
|
||||||
update_db_yaml(database_config_gp, path = source_path, logger=logger)
|
# Экспорт дашборда во временную директорию
|
||||||
|
zip_content, filename = from_c.export_dashboard(dashboard_id, logger=logger)
|
||||||
|
|
||||||
|
# Сохранение и распаковка во временную директорию
|
||||||
|
zip_path, unpacked_path = save_and_unpack_dashboard(
|
||||||
|
zip_content=zip_content,
|
||||||
|
original_filename=filename,
|
||||||
|
unpack=True,
|
||||||
|
logger=logger,
|
||||||
|
output_dir=temp_root
|
||||||
|
)
|
||||||
|
|
||||||
|
# Обновление конфигураций
|
||||||
|
source_path = unpacked_path / Path(filename).stem
|
||||||
|
update_db_yaml(database_config_click, path=source_path, logger=logger)
|
||||||
|
update_db_yaml(database_config_gp, path=source_path, logger=logger)
|
||||||
|
|
||||||
create_dashboard_export(f"{dashboard_slug}.zip",[source_path],logger=logger)
|
# Создание нового экспорта во временной директории
|
||||||
|
temp_zip = temp_root / f"{dashboard_slug}.zip"
|
||||||
|
create_dashboard_export(temp_zip, [source_path], logger=logger)
|
||||||
|
|
||||||
zip_path = Path(f"{dashboard_slug}.zip")
|
# Импорт обновленного дашборда
|
||||||
to_c.import_dashboard(zip_path)
|
to_c.import_dashboard(temp_zip)
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class SupersetClient:
|
|||||||
self.session = requests.Session()
|
self.session = requests.Session()
|
||||||
self._setup_session()
|
self._setup_session()
|
||||||
self._authenticate()
|
self._authenticate()
|
||||||
|
|
||||||
def _setup_session(self):
|
def _setup_session(self):
|
||||||
adapter = requests.adapters.HTTPAdapter(
|
adapter = requests.adapters.HTTPAdapter(
|
||||||
max_retries=3,
|
max_retries=3,
|
||||||
@@ -28,7 +28,7 @@ class SupersetClient:
|
|||||||
if not self.config.verify_ssl:
|
if not self.config.verify_ssl:
|
||||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
self.logger.debug(f"Проверка сертификатов SSL отключена")
|
self.logger.debug(f"Проверка сертификатов SSL отключена")
|
||||||
|
|
||||||
self.session.mount('https://', adapter)
|
self.session.mount('https://', adapter)
|
||||||
self.session.verify = self.config.verify_ssl
|
self.session.verify = self.config.verify_ssl
|
||||||
|
|
||||||
@@ -48,11 +48,12 @@ class SupersetClient:
|
|||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
self.access_token = response.json()["access_token"]
|
self.access_token = response.json()["access_token"]
|
||||||
self.logger.info(f"Токен Bearer {self.access_token} получен c {login_url}")
|
self.logger.info(
|
||||||
|
f"Токен Bearer {self.access_token} получен c {login_url}")
|
||||||
|
|
||||||
# Затем получаем CSRF токен с использованием access_token
|
# Затем получаем CSRF токен с использованием access_token
|
||||||
csrf_url = f"{self.config.base_url}/security/csrf_token/"
|
csrf_url = f"{self.config.base_url}/security/csrf_token/"
|
||||||
|
|
||||||
response = self.session.get(
|
response = self.session.get(
|
||||||
csrf_url,
|
csrf_url,
|
||||||
headers={"Authorization": f"Bearer {self.access_token}"},
|
headers={"Authorization": f"Bearer {self.access_token}"},
|
||||||
@@ -61,14 +62,15 @@ class SupersetClient:
|
|||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
self.csrf_token = response.json()["result"]
|
self.csrf_token = response.json()["result"]
|
||||||
self.logger.info(f"Токен CSRF {self.csrf_token} получен c {csrf_url}")
|
self.logger.info(
|
||||||
|
f"Токен CSRF {self.csrf_token} получен c {csrf_url}")
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
if e.response.status_code == 401:
|
if e.response.status_code == 401:
|
||||||
error_msg = f"Неверные данные для аутенфикации для {login_url}" if "login" in e.request.url else f"Не удалось получить CSRF токен с {csrf_url}"
|
error_msg = f"Неверные данные для аутенфикации для {login_url}" if "login" in e.request.url else f"Не удалось получить CSRF токен с {csrf_url}"
|
||||||
self.logger.error(f"Ошибка получения: {error_msg}")
|
self.logger.error(f"Ошибка получения: {error_msg}")
|
||||||
raise AuthenticationError(f"{error_msg}. Проверь данные аутенфикации") from e
|
raise AuthenticationError(
|
||||||
|
f"{error_msg}. Проверь данные аутенфикации") from e
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def headers(self):
|
def headers(self):
|
||||||
@@ -79,14 +81,15 @@ class SupersetClient:
|
|||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_dashboard(self, dashboard_id_or_slug: str ) -> Dict:
|
def get_dashboard(self, dashboard_id_or_slug: str) -> Dict:
|
||||||
"""
|
"""
|
||||||
Получаем информацию по дашборду (если передан dashboard_id_or_slug), либо по всем дашбордам, если параметр не передан
|
Получаем информацию по дашборду (если передан dashboard_id_or_slug)
|
||||||
Параметры:
|
Параметры:
|
||||||
:dashboard_id_or_slug - id или короткая ссылка
|
:dashboard_id_or_slug - id или короткая ссылка
|
||||||
"""
|
"""
|
||||||
url = f"{self.config.base_url}/dashboard/{dashboard_id_or_slug}"
|
url = f"{self.config.base_url}/dashboard/{dashboard_id_or_slug}"
|
||||||
self.logger.debug(f"Получаем информацию по дашборду с /{url}...")
|
self.logger.debug(f"Получаем информацию по дашборду с /{url}...")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = self.session.get(
|
response = self.session.get(
|
||||||
url,
|
url,
|
||||||
@@ -94,12 +97,14 @@ class SupersetClient:
|
|||||||
timeout=self.config.timeout
|
timeout=self.config.timeout
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
self.logger.info(f"ОК - Получили информацию по дашборду с {url}")
|
self.logger.info(f"ОК - Получили информацию по дашборду с {response.url}")
|
||||||
|
|
||||||
return response.json()["result"]
|
return response.json()["result"]
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
self.logger.error(f"Ошибка при получении информации о дашборде: {str(e)}", exc_info=True)
|
self.logger.error(
|
||||||
raise SupersetAPIError(f"Ошибка при получении информации о дашборде: {str(e)}") from e
|
f"Ошибка при получении информации о дашборде: {str(e)}", exc_info=True)
|
||||||
|
raise SupersetAPIError(
|
||||||
|
f"Ошибка при получении информации о дашборде: {str(e)}") from e
|
||||||
|
|
||||||
def get_dashboards(self, query: Optional[Dict] = None) -> Tuple[int, List[Dict]]:
|
def get_dashboards(self, query: Optional[Dict] = None) -> Tuple[int, List[Dict]]:
|
||||||
"""
|
"""
|
||||||
@@ -117,20 +122,25 @@ class SupersetClient:
|
|||||||
all_results: List[Dict] = []
|
all_results: List[Dict] = []
|
||||||
total_count: int = 0
|
total_count: int = 0
|
||||||
current_page: int = 0
|
current_page: int = 0
|
||||||
|
q_param = '{ "columns": [ "id" ], "page": 0, "page_size": 20}'
|
||||||
try:
|
try:
|
||||||
total_count = self.session.get(
|
response = self.session.get(
|
||||||
url,
|
url=f"{url}?q={q_param}",
|
||||||
#q=modified_query,
|
#params={"q": json.dumps(default_query)}, # Передаем такой body, иначе на prodta отдает 1 дашборд
|
||||||
headers=self.headers,
|
headers=self.headers,
|
||||||
timeout=self.config.timeout
|
timeout=self.config.timeout
|
||||||
).json()['count']
|
)
|
||||||
self.logger.info(f"ОК - Получили кол-во дашбордов ({total_count}) с {url}")
|
total_count = response.json()['count']
|
||||||
|
self.logger.info(
|
||||||
|
f"ОК - Получили кол-во дашбордов ({total_count}) с {url}")
|
||||||
|
self.logger.info(f"Запрос - {response.url}")
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
self.logger.error(f"Ошибка при получении кол-ва дашбордов: {str(e)}", exc_info=True)
|
self.logger.error(
|
||||||
raise SupersetAPIError(f"Ошибка при получении кол-ва дашбордов: {str(e)}") from e
|
f"Ошибка при получении кол-ва дашбордов: {str(e)}", exc_info=True)
|
||||||
#Инициализация параметров запроса с учетом переданного query
|
raise SupersetAPIError(
|
||||||
|
f"Ошибка при получении кол-ва дашбордов: {str(e)}") from e
|
||||||
|
# Инициализация параметров запроса с учетом переданного query
|
||||||
|
|
||||||
if query:
|
if query:
|
||||||
modified_query = query.copy()
|
modified_query = query.copy()
|
||||||
# Убедимся, что page_size установлен, если не передан
|
# Убедимся, что page_size установлен, если не передан
|
||||||
@@ -150,18 +160,15 @@ class SupersetClient:
|
|||||||
|
|
||||||
page_size = modified_query["page_size"]
|
page_size = modified_query["page_size"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
total_pages = (total_count + page_size - 1) // page_size
|
total_pages = (total_count + page_size - 1) // page_size
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while current_page < total_pages:
|
while current_page < total_pages:
|
||||||
modified_query["page"] = current_page
|
modified_query["page"] = current_page
|
||||||
response = self.session.get(
|
response = self.session.get(
|
||||||
url,
|
url,
|
||||||
headers=self.headers,
|
headers=self.headers,
|
||||||
params={"q": json.dumps(modified_query)} ,
|
params={"q": json.dumps(modified_query)},
|
||||||
timeout=self.config.timeout
|
timeout=self.config.timeout
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
@@ -170,11 +177,13 @@ class SupersetClient:
|
|||||||
current_page += 1
|
current_page += 1
|
||||||
|
|
||||||
self.logger.info(f"ОК - Получили информацию по дашбордам с {url}")
|
self.logger.info(f"ОК - Получили информацию по дашбордам с {url}")
|
||||||
# Проверка, достигли ли последней страницы
|
# Проверка, достигли ли последней страницы
|
||||||
return total_count, all_results
|
return total_count, all_results
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
self.logger.error(f"Ошибка при получении информации о дашбордах: {str(e)}", exc_info=True)
|
self.logger.error(
|
||||||
raise SupersetAPIError(f"Ошибка при получении информации о дашбордах: {str(e)}") from e
|
f"Ошибка при получении информации о дашбордах: {str(e)}", exc_info=True)
|
||||||
|
raise SupersetAPIError(
|
||||||
|
f"Ошибка при получении информации о дашбордах: {str(e)}") from e
|
||||||
|
|
||||||
def export_dashboard(self, dashboard_id: int, logger: Optional[SupersetLogger] = None) -> Tuple[bytes, str]:
|
def export_dashboard(self, dashboard_id: int, logger: Optional[SupersetLogger] = None) -> Tuple[bytes, str]:
|
||||||
"""Экспортирует дашборд из Superset в виде ZIP-архива и возвращает его содержимое с именем файла.
|
"""Экспортирует дашборд из Superset в виде ZIP-архива и возвращает его содержимое с именем файла.
|
||||||
@@ -209,7 +218,7 @@ class SupersetClient:
|
|||||||
params = {"q": f"[{dashboard_id}]"}
|
params = {"q": f"[{dashboard_id}]"}
|
||||||
logger = logger or SupersetLogger(name="client", console=False)
|
logger = logger or SupersetLogger(name="client", console=False)
|
||||||
self.logger.debug(f"Экспортируем дашборд ID {dashboard_id} c {url}...")
|
self.logger.debug(f"Экспортируем дашборд ID {dashboard_id} c {url}...")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = self.session.get(
|
response = self.session.get(
|
||||||
url,
|
url,
|
||||||
@@ -218,15 +227,15 @@ class SupersetClient:
|
|||||||
timeout=self.config.timeout
|
timeout=self.config.timeout
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
filename = get_filename_from_headers(response.headers) or f"dashboard_{dashboard_id}.zip"
|
filename = get_filename_from_headers(
|
||||||
|
response.headers) or f"dashboard_{dashboard_id}.zip"
|
||||||
self.logger.info(f"Дашборд сохранен в {filename}")
|
self.logger.info(f"Дашборд сохранен в {filename}")
|
||||||
return response.content, filename
|
return response.content, filename
|
||||||
|
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
self.logger.error(f"Ошибка при экспорте: {str(e)}", exc_info=True)
|
self.logger.error(f"Ошибка при экспорте: {str(e)}", exc_info=True)
|
||||||
raise SupersetAPIError(f"Export failed: {str(e)}") from e
|
raise SupersetAPIError(f"Export failed: {str(e)}") from e
|
||||||
|
|
||||||
|
|
||||||
def import_dashboard(self, zip_path) -> Dict:
|
def import_dashboard(self, zip_path) -> Dict:
|
||||||
"""Импортирует дашборд в Superset из ZIP-архива.
|
"""Импортирует дашборд в Superset из ZIP-архива.
|
||||||
@@ -260,8 +269,9 @@ class SupersetClient:
|
|||||||
"""
|
"""
|
||||||
url = f"{self.config.base_url}/dashboard/import/"
|
url = f"{self.config.base_url}/dashboard/import/"
|
||||||
self.logger.debug(f"Импортируем дашборд ID {zip_path} на {url}...")
|
self.logger.debug(f"Импортируем дашборд ID {zip_path} на {url}...")
|
||||||
headers_without_content_type = {k: v for k, v in self.headers.items() if k.lower() != 'content-type'}
|
headers_without_content_type = {
|
||||||
|
k: v for k, v in self.headers.items() if k.lower() != 'content-type'}
|
||||||
|
|
||||||
zip_name = zip_path.name
|
zip_name = zip_path.name
|
||||||
# Подготавливаем данные для multipart/form-data
|
# Подготавливаем данные для multipart/form-data
|
||||||
with open(zip_path, 'rb') as f:
|
with open(zip_path, 'rb') as f:
|
||||||
@@ -272,15 +282,15 @@ class SupersetClient:
|
|||||||
'application/x-zip-compressed' # MIME-тип из curl
|
'application/x-zip-compressed' # MIME-тип из curl
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Отправляем запрос
|
# Отправляем запрос
|
||||||
response = self.session.post(
|
response = self.session.post(
|
||||||
url,
|
url,
|
||||||
files=files,
|
files=files,
|
||||||
data={'overwrite': 'true'},
|
data={'overwrite': 'true'},
|
||||||
headers=headers_without_content_type,
|
headers=headers_without_content_type,
|
||||||
timeout=self.config.timeout * 2 # Longer timeout for imports
|
timeout=self.config.timeout * 2 # Longer timeout for imports
|
||||||
)
|
)
|
||||||
# Обрабатываем ответ
|
# Обрабатываем ответ
|
||||||
try:
|
try:
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
@@ -291,4 +301,4 @@ class SupersetClient:
|
|||||||
error_detail = f"{e.response.status_code} {e.response.reason}"
|
error_detail = f"{e.response.status_code} {e.response.reason}"
|
||||||
if e.response.text:
|
if e.response.text:
|
||||||
error_detail += f"\nТело ответа: {e.response.text}"
|
error_detail += f"\nТело ответа: {e.response.text}"
|
||||||
raise RuntimeError(f"Ошибка импорта: {error_detail}") from e
|
raise RuntimeError(f"Ошибка импорта: {error_detail}") from e
|
||||||
|
|||||||
@@ -13,24 +13,35 @@ from ..utils.logger import SupersetLogger
|
|||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def create_temp_file(
|
def create_temp_file(
|
||||||
content: bytes,
|
content: Optional[bytes] = None,
|
||||||
suffix: str = ".zip",
|
suffix: str = ".zip",
|
||||||
|
mode: str = 'wb',
|
||||||
logger: Optional[SupersetLogger] = None
|
logger: Optional[SupersetLogger] = None
|
||||||
):
|
):
|
||||||
"""Контекстный менеджер для создания временных файлов с логированием"""
|
"""Расширенный контекстный менеджер для временных файлов/директорий"""
|
||||||
logger = logger or SupersetLogger(name="fileio", console=False)
|
logger = logger or SupersetLogger(name="fileio", console=False)
|
||||||
try:
|
try:
|
||||||
logger.debug(f"Создание временного файла с суффиксом {suffix}")
|
logger.debug(f"Создание временного ресурса с суффиксом {suffix}")
|
||||||
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp:
|
|
||||||
tmp.write(content)
|
# Для директорий
|
||||||
tmp.flush()
|
if suffix.startswith('.dir'):
|
||||||
yield Path(tmp.name)
|
with tempfile.TemporaryDirectory(suffix=suffix) as tmp_dir:
|
||||||
|
logger.debug(f"Создана временная директория: {tmp_dir}")
|
||||||
|
yield Path(tmp_dir)
|
||||||
|
|
||||||
|
# Для файлов
|
||||||
|
else:
|
||||||
|
with tempfile.NamedTemporaryFile(suffix=suffix, mode=mode, delete=False) as tmp:
|
||||||
|
if content:
|
||||||
|
tmp.write(content)
|
||||||
|
tmp.flush()
|
||||||
|
logger.debug(f"Создан временный файл: {tmp.name}")
|
||||||
|
yield Path(tmp.name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(
|
logger.error(f"Ошибка создания временного ресурса: {str(e)}", exc_info=True)
|
||||||
f"Ошибка создания временного файла: {str(e)}", exc_info=True)
|
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
if Path(tmp.name).exists():
|
if 'tmp' in locals() and Path(tmp.name).exists() and not suffix.startswith('.dir'):
|
||||||
Path(tmp.name).unlink()
|
Path(tmp.name).unlink()
|
||||||
logger.debug(f"Временный файл {tmp.name} удален")
|
logger.debug(f"Временный файл {tmp.name} удален")
|
||||||
|
|
||||||
|
|||||||
32
test api.py
32
test api.py
@@ -65,10 +65,10 @@ def setup_clients():
|
|||||||
clients['dev'] = SupersetClient(dev_config)
|
clients['dev'] = SupersetClient(dev_config)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Ошибка инициализации клиента: {str(e)}")
|
logger.error(f"Ошибка инициализации клиента: {str(e)}")
|
||||||
try:
|
# try:
|
||||||
clients['sbx'] = SupersetClient(sandbox_config)
|
# clients['sbx'] = SupersetClient(sandbox_config)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
logger.error(f"Ошибка инициализации клиента: {str(e)}")
|
# logger.error(f"Ошибка инициализации клиента: {str(e)}")
|
||||||
try:
|
try:
|
||||||
clients['prod'] = SupersetClient(prod_config)
|
clients['prod'] = SupersetClient(prod_config)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -84,19 +84,7 @@ def backup_dashboards(client, env_name, backup_root):
|
|||||||
#logger.info(f"Начало бэкапа для окружения {env_name}")
|
#logger.info(f"Начало бэкапа для окружения {env_name}")
|
||||||
|
|
||||||
#print(client.get_dashboards())
|
#print(client.get_dashboards())
|
||||||
# dashboard_count,dashboard_meta = client.get_dashboards()
|
print(client.get_dashboard("IM0010"))
|
||||||
# total = 0
|
|
||||||
# success = 0
|
|
||||||
# i=1
|
|
||||||
# for db in dashboard_meta:
|
|
||||||
# #total += 1
|
|
||||||
# #print(total)
|
|
||||||
# if db['slug']:
|
|
||||||
# success+=1
|
|
||||||
# print(f"{db['dashboard_title']} {i}. {db['id']}")
|
|
||||||
# i+=1
|
|
||||||
# for db in dashboard_meta:
|
|
||||||
# print(f"DB Id = {db["id"]} DB title = {db["dashboard_title"]} DB SLUG - {db["slug"]}")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -112,11 +100,11 @@ dev_success = backup_dashboards(
|
|||||||
|
|
||||||
|
|
||||||
# Бэкап для Sandbox
|
# Бэкап для Sandbox
|
||||||
sbx_success = backup_dashboards(
|
# sbx_success = backup_dashboards(
|
||||||
clients['sbx'],
|
# clients['sbx'],
|
||||||
"SBX",
|
# "SBX",
|
||||||
superset_backup_repo
|
# superset_backup_repo
|
||||||
)
|
# )
|
||||||
|
|
||||||
prod_success = backup_dashboards(
|
prod_success = backup_dashboards(
|
||||||
clients['prod'],
|
clients['prod'],
|
||||||
|
|||||||
Reference in New Issue
Block a user