Soda Core

repository·main·Indexed 25 days ago

https://github.com/sodadata/soda-core

An open-source data quality and data contract verification engine. Soda Core allows developers to define data quality rules in YAML and validate schemas and data across platforms such as Snowflake, BigQuery, PostgreSQL, and Athena via a CLI or Python API. It supports local contract verification, remote execution via Soda Runner, and integration with Soda Cloud for centralized contract management.

Tokens
23.2K
Snippets
26
Records
151
Agent score
81%

What's inside soda-core

  1. How SQL Server capability derivation works

    main

    Soda Core uses a three-step process to determine if specific SQL features (like APPROX_PERCENTILE_DISC) are supported by your SQL Server instance. This ensures that the correct SQL syntax is generated based on your specific engine version and edition.

    1. Detection: When a connection is opened via SqlServerDataSourceConnection, Soda Core eagerly probes the server for its server_major_version (via pyodbc.SQL_DBMS_VER) and its engine_edition (via SELECT CAST(SERVERPROPERTY('EngineEdition') AS INT)).
    2. Sync: The SqlServerDataSourceImpl synchronizes these raw facts from the connection onto the SqlServerSqlDialect instance.
    3. Derivation: The SqlServerSqlDialect uses these facts to calculate support. For example, it checks if the version is $\ge 16$ (SQL Server 2022) or if the engine edition matches Azure SQL Database (5) or Managed Instance (8).

    Note on Offline/Snapshot Replay: If no server facts are available (e.g., during offline rendering or snapshot replay), Soda Core assumes the newest engine version and enables capabilities by default.

  2. Create and verify a data contract locally

    main

    A data contract is a YAML file defining schema and data quality checks for a specific dataset.

    Example contract.yml:

    # contract.yml 
    
    dataset: postgres_ds/db/schema/dataset
    
    checks: # dataset level checks
      - schema:
      - row_count: 
    
    columns: # columns block
      - name: id
        checks: # column level checks 
          - missing:
      - name: name
        checks:
          - missing:
              threshold:
                metric: percent
                must_be_less_than: 10
      - name: size
        checks:
          - invalid:
              valid_values: ['S', 'M', 'L'] 

    Note: The dataset identifier (e.g., postgres_ds/db/schema/dataset) must match the name property in your data source configuration.

    Verify the contract: Run a scan to evaluate the contract against your data.

    soda contract verify -ds ds_config.yml -c contract.yml
    • -ds, --data-source (Required): Path to the data source YAML file.
    • -c, --contract (Required): Path to the data contract YAML file.
  3. Connect to and interact with Soda Cloud

    main

    You can manage contracts centrally and execute checks remotely by connecting Soda Core to Soda Cloud.

    1. Create a Soda Cloud config:
      soda cloud create -f sc_config.yml
       - `-f`, `--file` (Required): Output file path for the Soda Cloud YAML configuration.
    
    2. **Test the Cloud connection:**
       ```bash
    soda cloud test -sc sc_config.yml
    • -sc, --soda-cloud (Required): Path to the Soda Cloud YAML file.
    1. Publish a contract to Soda Cloud: Use this to set a contract as the source of truth in the cloud.
      soda contract publish -c contract.yml -sc sc_config.yml
    
    4. **Publish verification results to Soda Cloud:**
       Add the `-p` flag to your verification command to upload results.
       ```bash
    soda contract verify -ds ds_config.yml -c contract.yml -sc sc_config.yml -p
    • -p, --publish (Optional): Publish results and contract to Soda Cloud. Requires "Manage contract" permission.
    soda cloud create -f sc_config.yml
    soda cloud test -sc sc_config.yml
    soda contract publish -c contract.yml -sc sc_config.yml
  4. Verify a contract remotely using Soda Runner

    main

    Instead of running checks locally, you can use Soda Runner (formerly Soda Agent) to execute verification via Soda Cloud.

    To launch verification, you need the Soda Cloud dataset identifier (found in the Soda Cloud UI) and your cloud configuration.

    soda contract verify -sc sc_config.yml -d postgres_ds/db/schema/dataset -r
    • -sc, --soda-cloud (Required): Path to a Soda Cloud YAML configuration file.
    • -d, --dataset (Required): Soda Cloud dataset identifier.
    • -r, --use-runner (Required): Use Soda Runner for execution. (Note: -a/--use-agent is a deprecated alias).
    • -p, --publish (Optional): Publish results and contract to Soda Cloud.
  5. Install Soda Core v4

    main

    Soda Core v4 packages are available on PyPI using the naming convention soda-{data source}. You can install them using uv (recommended) or pip.

    Using UV (recommended):

    uv pip install soda-postgres

    Using pip:

    pip install soda-postgres

    Replace soda-postgres with the appropriate package for your data source (e.g., soda-snowflake, soda-bigquery, soda-duckdb).

  6. Install legacy Soda Core v3

    main

    Version 3 packages use the naming convention soda-core-{data source}. To install a specific version (e.g., 3.5.x) for Postgres, use:

    Using UV:

    uv pip install soda-core-postgres~=3.5.0

    Using pip:

    pip install soda-core-postgres~=3.5.0
  7. Set up a local Trino instance for JWT testing

    main

    You can use the provided docker-compose.yml and configuration files to launch a local Trino instance configured for both JWT authentication and username/password authentication. The default credentials for the password.db are username soda-test and password soda-test.

    Follow these steps to set up the environment:

    1. Generate keys: Run the key generation script from within the local_instance directory.
    2. Start Trino: Use Docker Compose to bring up the services.
    3. Verify instance: Use curl to ensure the instance is responding to queries.
  8. Configure and test a data source

    main

    Before running checks, you must define and validate your data source connection.

    1. Create a data source configuration file: Use soda data-source create to generate a YAML template. By default, it generates a PostgreSQL template.
      soda data-source create -f ds_config.yml
       - `-f`, `--file` (Required): Output file path for the YAML configuration.
    
    2. **Test the connection:**
       Validate the configuration against your actual data source.
       ```bash
    soda data-source test -ds ds_config.yml
    • -ds, --data-source (Required): Path to the data source YAML file.
    soda data-source create -f ds_config.yml
    soda data-source test -ds ds_config.yml
  9. Configure Spark DataFrame connections in Soda

    main

    When using the sparkdf data source, you must specify a connection mode in your configuration. Soda supports four distinct connection modes for Spark DataFrames. You must provide exactly one of the following sets of properties to avoid configuration conflicts.

    1. Existing Session Mode

    Use this when you have an already instantiated SparkSession object in your Python environment (e.g., in a Databricks notebook or a local script).

    • Key: spark_session (the actual SparkSession object)

    2. Active Session Mode

    Use this to automatically pick up the session currently active in the current thread via SparkSession.getActiveSession(). This is useful for reusing the existing spark object in notebooks without passing it explicitly.

    • Key: use_active_session: true

    3. Remote Session Mode (Spark Connect)

    Use this to connect to a remote workspace (like Databricks) via Spark Connect. This mode builds a session using SparkSession.builder.remote(<uri>).getOrCreate().

    • Keys:
      • host: The workspace host (e.g., dbc-12345.cloud.databricks.com). Note: You can provide the full URL with https://, and Soda will strip the scheme automatically.
      • token: Your Personal Access Token (PAT).
      • cluster_id: The ID of the cluster to route the session to.

    4. New Session Mode

    Use this to trigger the creation of a fresh Spark session.

    • Key: new_session: true (default behavior)
  10. How SparkDataFrameDataSource handles namespaces

    main

    The way namespaces (prefixes) are handled depends on whether use_catalog is enabled:

    • Legacy Mode (use_catalog=False): Uses a 1-level prefix [schema]. Commands like CREATE SCHEMA IF NOT EXISTS will only use the schema name.
    • Catalog Mode (use_catalog=True): Uses a 2-level prefix [catalog, schema]. This is required for Unity Catalog-style 3-level namespaces (catalog.schema.table).