8000 Added more options for materialized views feature by baixin137 · Pull Request #394 · tableau/server-client-python · GitHub
[go: up one dir, main page]

Skip to content

Added more options for materialized views feature #394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 103 additions & 29 deletions samples/materialize_workbooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,22 @@ def main():
parser.add_argument('--server', '-s', required=True, help='Tableau server address')
parser.add_argument('--username', '-u', required=True, help='username to sign into server')
parser.add_argument('--password', '-p', required=False, help='password to sign into server')
parser.add_argument('--mode', '-m', required=False, choices=['enable', 'disable'],
parser.add_argument('--mode', '-m', required=False, choices=['disable', 'enable', 'enable_all', 'enable_selective'],
help='enable/disable materialized views for sites/workbooks')
parser.add_argument('--status', '-st', required=False, action='store_true',
help='show materialized views enabled sites/workbooks')
parser.add_argument('--site-id', '-si', required=False,
help='set to Default site by default')
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
help='desired logging level (set to error by default)')
parser.add_argument('--type', '-t', required=False, choices=['site', 'workbook', 'project_name',
'project_id', 'project_path'],
parser.add_argument('--type', '-t', required=False, choices=['site', 'workbook', 'project_name', 'project_path'],
help='type of content you want to update materialized views settings on')
parser.add_argument('--path-list', '-pl', required=False, help='path to a list of workbook paths')
parser.add_argument('--name-list', '-nl', required=False, help='path to a list of workbook names')
parser.add_argument('--project-name', '-pn', required=False, help='name of the project')
parser.add_argument('--project-path', '-pp', required=False, help="path of the project")
parser.add_argument('--materialize-now', '-mn', required=False, action='store_true',
help='create materialized views for workbooks immediately')

args = parser.parse_args()

Expand All @@ -38,32 +39,32 @@ def main():

# site content url is the TSC term for site id
site_content_url = args.site_id if args.site_id is not None else ""
enable_materialized_views = args.mode == "enable"

if (args.type is None) != (args.mode is None):
print("Use '--type <content type> --mode <enable/disable>' to update materialized views settings.")
if not assert_options_valid(args):
return

materialized_views_config = create_materialized_views_config(args)

# enable/disable materialized views for site
if args.type == 'site':
if not update_site(args, enable_materialized_views, password, site_content_url):
if not update_site(args, password, site_content_url):
return

# enable/disable materialized views for workbook
# works only when the site the workbooks belong to are enabled too
elif args.type == 'workbook':
if not update_workbook(args, enable_materialized_views, password, site_content_url):
if not update_workbook(args, materialized_views_config, password, site_content_url):
return

# enable/disable materialized views for project by project name
# will show possible projects when project name is not unique
elif args.type == 'project_name':
if not update_project_by_name(args, enable_materialized_views, password, site_content_url):
if not update_project_by_name(args, materialized_views_config, password, site_content_url):
return

# enable/disable materialized views for proejct by project path, for example: project1/project2
# enable/disable materialized views for project by project path, for example: project1/project2
elif args.type == 'project_path':
if not update_project_by_path(args, enable_materialized_views, password, site_content_url):
if not update_project_by_path(args, materialized_views_config, password, site_content_url):
return

# show enabled sites and workbooks
Expand Down Expand Up @@ -108,7 +109,7 @@ def show_materialized_views_status(args, password, site_content_url):
# only server admins can get all the sites in the server
# other users can only get the site they are in
for site in TSC.Pager(server.sites):
if site.materialized_views_enabled:
if site.materialized_views_mode != "disable":
enabled_sites.add(site)
print("Site name: {}".format(site.name))
print('\n')
Expand All @@ -119,34 +120,42 @@ def show_materialized_views_status(args, password, site_content_url):
site_auth = TSC.TableauAuth(args.username, password, site.content_url)
with server.auth.sign_in(site_auth):
for workbook in TSC.Pager(server.workbooks):
if workbook.materialized_views_enabled:
if workbook.materialized_views_config['materialized_views_enabled']:
print("Workbook: {} from site: {}".format(workbook.name, site.name))


def update_project_by_path(args, enable_materialized_views, password, site_content_url):
def update_project_by_path(args, materialized_views_mode, password, site_content_url):
if args.project_path is None:
print("Use --project_path <project path> to specify the path of the project")
return False
tableau_auth = TSC.TableauAuth(args.username, password, site_content_url)
server = TSC.Server(args.server, use_server_version=True)
project_name = args.project_path.split('/')[-1]
with server.auth.sign_in(tableau_auth):
if not assert_site_enabled_for_materialized_views(server, site_content_url):
return False
projects = [project for project in TSC.Pager(server.projects) if project.name == project_name]
if not assert_project_valid(args.project_path, projects):
return False

possible_paths = get_project_paths(server, projects)
update_project(possible_paths[args.project_path], server, enable_materialized_views)
update_project(possible_paths[args.project_path], server, materialized_views_mode)
return True


def update_project_by_name(args, enable_materialized_views, password, site_content_url):
def update_project_by_name(args, materialized_views_config, password, site_content_url):
if args.project_name is None:
print("Use --project-name <project name> to specify the name of the project")
return False
tableau_auth = TSC.TableauAuth(args.username, password, site_content_url)
server = TSC.Server(args.server, use_server_version=True)
with server.auth.sign_in(tableau_auth):
if not assert_site_enabled_for_materialized_views(server, site_content_url):
return False
# get all projects with given name
projects = [project for project in TSC.Pager(server.projects) if project.name == args.project_name]
if not assert_project_valid(args.project_name, projects):
return False

if len(projects) > 1:
possible_paths = get_project_paths(server, projects)
Expand All @@ -156,20 +165,28 @@ def update_project_by_name(args, enable_materialized_views, password, site_conte
print('\n')
return False
else:
update_project(projects[0], server, enable_materialized_views)
update_project(projects[0], server, materialized_views_config)
return True


def update_project(project, server, enable_materialized_views):
def update_project(project, server, materialized_views_config):
all_projects = list(TSC.Pager(server.projects))
project_ids = find_project_ids_to_update(all_projects, project, server)
for workbook in TSC.Pager(server.workbooks):
if workbook.project_id == project.id:
workbook.materialized_views_enabled = enable_materialized_views
if workbook.project_id in project_ids:
workbook.materialized_views_config = materialized_views_config
server.workbooks.update(workbook)

print("Updated materialized views settings for project: {}".format(project.name))
print('\n')


def find_project_ids_to_update(all_projects, project, server):
projects_to_update = []
find_projects_to_update(project, server, all_projects, projects_to_update)
return set([project_to_update.id for project_to_update in projects_to_update])


def parse_workbook_path(file_path):
# parse the list of project path of workbooks
workbook_paths = open(file_path, 'r')
Expand All @@ -180,24 +197,26 @@ def parse_workbook_path(file_path):
return workbook_path_mapping


def update_workbook(args, enable_materialized_views, password, site_content_url):
def update_workbook(args, materialized_views_config, password, site_content_url):
if args.path_list is None and args.name_list is None:
print("Use '--path-list <filename>' or '--name-list <filename>' to specify the path of a list of workbooks")
print('\n')
return False
tableau_auth = TSC.TableauAuth(args.username, password, site_id=site_content_url)
server = TSC.Server(args.server, use_server_version=True)
with server.auth.sign_in(tableau_auth):
if not assert_site_enabled_for_materialized_views(server, site_content_url):
return False
if args.path_list is not None:
workbook_path_mapping = parse_workbook_path(args.path_list)
all_projects = {p 8000 roject.id: project for project in TSC.Pager(server.projects)}
update_workbooks_by_paths(all_projects, enable_materialized_views, server, workbook_path_mapping)
update_workbooks_by_paths(all_projects, materialized_views_config, server, workbook_path_mapping)
elif args.name_list is not None:
update_workbooks_by_names(args.name_list, server, enable_materialized_views)
update_workbooks_by_names(args.name_list, server, materialized_views_config)
return True


def update_workbooks_by_paths(all_projects, enable_materialized_views, server, workbook_path_mapping):
def update_workbooks_by_paths(all_projects, materialized_views_config, server, workbook_path_mapping):
for workbook_name, workbook_paths in workbook_path_mapping.items():
req_option = TSC.RequestOptions()
req_option.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name,
Expand All @@ -207,13 +226,13 @@ def update_workbooks_by_paths(all_projects, enable_materialized_views, server, w
for workbook in workbooks:
path = find_project_path(all_projects[workbook.project_id], all_projects, "")
if path in workbook_paths:
workbook.materialized_views_enabled = enable_materialized_views
workbook.materialized_views_config = materialized_views_config
server.workbooks.update(workbook)
print("Updated materialized views settings for workbook: {}".format(path + '/' + workbook.name))
print('\n')


def update_workbooks_by_names(name_list, server, enable_materialized_views):
def update_workbooks_by_names(name_list, server, materialized_views_config):
workbook_names = open(name_list, 'r')
for workbook_name in workbook_names:
req_option = TSC.RequestOptions()
Expand All @@ -222,24 +241,79 @@ def update_workbooks_by_names(name_list, server, enable_materialized_views):
workbook_name.rstrip()))
workbooks = list(TSC.Pager(server.workbooks, req_option))
for workbook in workbooks:
workbook.materialized_views_enabled = enable_materialized_views
workbook.materialized_views_config = materialized_views_config
server.workbooks.update(workbook)
print("Updated materialized views settings for workbook: {}".format(workbook.name))
print('\n')


def update_site(args, enable_materialized_views, password, site_content_url):
def update_site(args, password, site_content_url):
if not assert_site_options_valid(args):
return False
tableau_auth = TSC.TableauAuth(args.username, password, site_id=site_content_url)
server = TSC.Server(args.server, use_server_version=True)
with server.auth.sign_in(tableau_auth):
site_to_update = server.sites.get_by_content_url(site_content_url)
site_to_update.materialized_views_enabled = enable_materialized_views
site_to_update.materialized_views_mode = args.mode

server.sites.update(site_to_update)
print("Updated materialized views settings for site: {}".format(site_to_update.name))
print('\n')
return True


def create_materialized_views_config(args):
materialized_views_config = dict()
materialized_views_config['materialized_views_enabled'] = args.mode == "enable"
materialized_views_config['run_materialization_now'] = True if args.materialize_now else False
return materialized_views_config


def assert_site_options_valid(args):
if args.materialize_now:
print('"--materialize-now" only applies to workbook/project type')
return False
if args.mode == 'enable':
print('For site type please choose from "disable", "enable_all", or "enable_selective"')
return False
return True


def assert_options_valid(args):
if args.type != "site" and args.mode in ("enable_all", "enable_selective"):
print('"enable_all" and "enable_selective" do not apply to workbook/project type')
return False
if (args.type is None) != (args.mode is None):
print("Use '--type <content type> --mode <mode>' to update materialized views settings.")
return False
return True


def assert_site_enabled_for_materialized_views(server, site_content_url):
parent_site = server.sites.get_by_content_url(site_content_url)
if parent_site.materialized_views_mode == "disable":
print('Cannot update workbook/project because site is disabled for materialized views')
return False
return True


def assert_project_valid(project_name, projects):
if len(projects) == 0:
print("Cannot find project: {}".format(project_name))
return False
return True


def find_projects_to_update(project, server, all_projects, projects_to_update):
# Use recursion to find all the sub-projects and enable/disable the workbooks in them
projects_to_update.append(project)
children_projects = [child for child in all_projects if child.parent_id == project.id]
if len(children_projects) == 0:
return

for child in children_projects:
find_projects_to_update(child, server, all_projects, projects_to_update)


if __name__ == "__main__":
main()
2 changes: 2 additions & 0 deletions samples/name.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
92 08 23
Book2
16 changes: 16 additions & 0 deletions tableauserverclient/models/property_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,19 @@ def wrapper(self, value):
dt = parse_datetime(value)
return func(self, dt)
return wrapper


def property_is_materialized_views_config(func):
@wraps(func)
def wrapper(self, value):
if not isinstance(value, dict):
raise ValueError("{} is not type 'dict', cannot update {})".format(value.__class__.__name__,
func.__name__))
if len(value) != 2 or not all(attr in value.keys() for attr in ('materialized_views_enabled',
'run_materialization_now')):
error = "{} should have 2 keys ".format(func.__name__)
error += "'materialized_views_enabled' and 'run_materialization_now'"
error += "instead you have {}".format(value.keys())
raise ValueError(error)
return func(self, value)
return wrapper
Loading
0