Example #1
0
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("")
Example #2
0
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
Example #3
0
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("")