def run_sql( project, branch, explores, base_url, client_id, client_secret, port, api_version, mode, remote_reset, concurrency, ) -> None: """Runs and validates the SQL for each selected LookML dimension.""" runner = Runner( base_url, project, branch, client_id, client_secret, port, api_version, remote_reset, ) errors = runner.validate_sql(explores, mode, concurrency) if errors: for error in sorted(errors, key=lambda x: x["path"]): printer.print_sql_error(error) logger.info("") raise ValidationError else: logger.info("")
def test_sql_error_prints_with_relevant_info(mock_log, sql_error, caplog): model = "model_a" explore = "explore_a" dimension = "view_a.dimension_a" message = "A super important error occurred." printer.print_sql_error( model=model, explore=explore, message=message, sql="SELECT * FROM test", log_dir="logs", ) assert "LookML:" not in caplog.text assert model in caplog.text assert explore in caplog.text assert message in caplog.text assert dimension not in caplog.text printer.print_sql_error( model=model, explore=explore, message=message, sql="SELECT * FROM test", log_dir=None, lookml_url="https://spectacles.looker.com", ) assert "LookML:" in caplog.text
def run_sql( log_dir, project, branch, explores, exclude, base_url, client_id, client_secret, port, api_version, mode, remote_reset, import_projects, concurrency, commit_ref, ) -> None: """Runs and validates the SQL for each selected LookML dimension.""" runner = Runner( base_url, project, branch, client_id, client_secret, port, api_version, remote_reset, import_projects, commit_ref, ) def iter_errors(lookml: List) -> Iterable: for item in lookml: if item.errored: yield item results = runner.validate_sql(explores, exclude, mode, concurrency) for test in sorted(results["tested"], key=lambda x: (x["model"], x["explore"])): message = f"{test['model']}.{test['explore']}" printer.print_validation_result(passed=test["passed"], source=message) errors = sorted( results["errors"], key=lambda x: (x["model"], x["explore"], x["metadata"].get("dimension")), ) if errors: for error in errors: printer.print_sql_error( model=error["model"], explore=error["explore"], message=error["message"], sql=error["metadata"]["sql"], log_dir=log_dir, dimension=error["metadata"].get("dimension"), lookml_url=error["metadata"].get("lookml_url"), ) if mode == "batch": logger.info( printer.dim( "\n\nTo determine the exact dimensions responsible for " f"{'this error' if len(errors) == 1 else 'these errors'}, " "you can re-run \nSpectacles in single-dimension mode, " "with `--mode single`.\n\nYou can also run this original " "validation with `--mode hybrid` to do this automatically." )) logger.info("") raise GenericValidationError else: logger.info("")