Saltar al contenido principal

Conocimiento

Construir productos de datos con dbt

dbt es una de las herramientas más populares para transformar datos. Así estructuramos los proyectos dbt como productos de datos, con propiedad clara, Output Ports, Data Contracts y tests de calidad. Y te enseñamos cómo usamos coding agents para implementar los productos de datos de forma automática.

¿Por qué dbt para productos de datos?

dbt (data build tool) es un framework de transformación SQL-first que funciona sobre data warehouses como Snowflake, BigQuery, Databricks, AWS Athena y DuckDB. Trae al mundo de los datos las buenas prácticas de la ingeniería de software: control de versiones, modularidad, testing y documentación.

Esas propiedades hacen que dbt encaje de forma natural a la hora de implementar productos de datos. Un proyecto dbt puede representar un producto de datos: tiene entradas claras, lógica de transformación, modelos de salida, tests y documentación, todo en un único repositorio Git con un equipo propietario.

Empieza por un Data Contract

Vamos con un ejemplo real: un producto de datos que en Entropy Data usamos internamente para customer success, y que nos ayuda a entender cómo usan nuestros clientes la aplicación y si podemos apoyarles de forma proactiva para que construyan mejores productos de datos con Data Contracts.

Antes de escribir ningún modelo dbt, empezamos definiendo un Data Contract para el producto de datos objetivo (o, más exactamente, para su Output Port). El Data Contract describe qué datos vas a tener que proporcionar, su esquema, sus garantías de calidad y sus condiciones de uso. Piensa en él como la especificación de requisitos de nuestro producto de datos.

Al diseñar primero el contrato, nos ponemos de acuerdo sobre qué información hace falta realmente antes de invertir tiempo en la implementación. Eso mantiene el producto de datos pequeño y manejable. Este enfoque contract-first evita construir conjuntos de datos que nadie usa o que no cumplen nuestras expectativas.

El Data Contract se escribe en formato ODCS y se guarda junto al SQL que gobierna, en models/output_ports/v1/:

# models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml

apiVersion: v3.1.0
kind: DataContract

id: entropydata-customer-activity-v1
name: Customer Activity
version: 1.0.0
status: draft

description:
  usage: analytics
  purpose: Customer activity within Entropy Data for customer success.

schema:
- name: customer_activity
  physicalType: table
  properties:
    - name: organization_id
      description: Unique identifier of the organization.
      logicalType: string
      required: true
      primaryKey: true
      examples:
        - 550e8400-e29b-41d4-a716-446655440000
    - name: organization_vanity_url
      description: Vanity URL of the organization.
      logicalType: string
      examples:
        - acme-corp
    - name: organization_created_by
      description: Email address of the user that created the organization.
      logicalType: string
      examples:
        - admin@acme.com
    - name: organization_created_at
      description: Timestamp when the organization was created.
      logicalType: timestamp
      examples:
        - "2024-03-15T10:00:00Z"
    - name: users_total
      description: Total number of users in the organization.
      logicalType: integer
      required: true
      examples:
        - 12
    - name: users_added_30d
      description: Number of users added in the last 30 days.
      logicalType: integer
      required: true
      examples:
        - 3
    - name: users_last_signed_up_at
      description: Timestamp when the last user signed up.
      logicalType: timestamp
      examples:
        - "2024-09-10T14:22:00Z"
    - name: dataproducts_total
      description: Total number of data products in the organization.
      logicalType: integer
      required: true
      examples:
        - 42
    - name: dataproducts_added_30d
      description: Number of data products added in the last 30 days.
      logicalType: integer
      required: true
      examples:
        - 5
    - name: dataproducts_outputports_total
      description: Total number of output ports across all data products.
      logicalType: integer
      required: true
      examples:
        - 58
    - name: dataproducts_outputports_with_datacontract_percentage
      description: Percentage of output ports that have an active data contract.
      logicalType: number
      required: true
      examples:
        - 72.5
    - name: dataproducts_outputports_with_testresults_percentage
      description: Percentage of output ports that have test results.
      logicalType: number
      required: true
      examples:
        - 65.0
    - name: dataproducts_last_updated_at
      description: Timestamp when the last data product was updated.
      logicalType: timestamp
      examples:
        - "2024-09-14T09:30:00Z"
    - name: assets_total
      description: Total number of assets in the organization.
      logicalType: integer
      required: true
      examples:
        - 87
    - name: data_platform
      description: The data contract / output port type used for most data products.
      logicalType: string
      examples:
        - bigquery
        - snowflake
        - s3
    - name: updated_at
      description: Timestamp when this record was written by the dbt execution.
      logicalType: timestamp
      required: true
      examples:
        - "2024-09-16T06:05:23Z"

team:
  name: customer-success

servers:
  - server: production
    type: databricks
    catalog: entropy_data_prod
    schema: dp_entropydata_customer_activity_v1

roles:
  - role: customer_success
    access: read

Un producto de datos que cumpla esta especificación ayudaría a nuestro equipo de customer success a identificar la actividad de un cliente y a saber de un vistazo cuál es su plataforma de datos objetivo.

En Entropy Data, el Data Contract se puede editar y gestionar desde el Data Contract Editor:

Vista de formulario del Data Contract Editor con las propiedades del esquema, los fundamentos y las condiciones de uso del Data Contract customer_activity.

Con el contrato ya definido, la implementación en dbt es directa: construir los modelos que lo cumplen.

Diseño del producto de datos

Nuestro producto de datos Customer Activity está alineado con el consumo: toma datos operacionales en bruto, los transforma y los sirve para un caso de uso concreto, customer success.

Diseño del producto de datos: la aplicación de Entropy Data fluye a través de un producto de datos alineado con la fuente que va de Postgres a Databricks y desemboca en el producto de datos Customer Activity, alineado con el consumo.

Los datos van desde nuestra aplicación Entropy Data Cloud (la base de datos operacional Postgres) a un producto de datos en bruto alineado con la fuente que extrae los datos de Postgres a Databricks (con dlt), y de ahí al producto de datos Customer Activity que queremos construir ahora con dbt.

Un proyecto dbt por producto de datos

Nuestro enfoque recomendado es un proyecto dbt por producto de datos. Cada proyecto pertenece a un equipo y vive en su propio repositorio Git, de forma que cada producto de datos se puede implementar y desplegar de manera independiente. Una buena práctica que aprendimos con los Self-contained Systems. Así se garantizan una propiedad clara y la autonomía, principios centrales del Data Mesh.

La estructura típica de un proyecto dbt de producto de datos es esta:

dp_entropydata_customer_activity/
├── dbt_project.yml
├── dp_entropydata_customer_activity.odps.yaml      # Data product spec (ODPS)
├── openlineage.yml                                 # OpenLineage transport config
├── profiles.yml.example
├── .github/workflows/data-product.yml              # CI: build, test, publish
├── models/
│   ├── input_ports/                                # External sources this product reads from
│   │   ├── _models.yml
│   │   ├── <provider-output-port-id>.source.yaml   # One file per active access agreement
│   │   └── <provider-output-port-id>.odcs.yaml     # Cached snapshot of upstream contract
│   ├── staging/                                    # Internal: 1:1 cleaned views over input ports
│   │   ├── _models.yml
│   │   ├── stg_organizations.sql
│   │   ├── stg_members.sql
│   │   ├── stg_data_products.sql
│   │   └── stg_assets.sql
│   ├── intermediate/                               # Internal: joined/shaped views with business logic
│   │   ├── _models.yml
│   │   └── int_customer_activity.sql
│   └── output_ports/v1/                            # Public: versioned output port models
│       ├── _models.yml
│       ├── customer_activity.sql
│       └── entropydata-customer-activity-v1.odcs.yaml   # Data contract (ODCS), colocated with the SQL
├── tests/                                          # Custom data tests
│   └── assert_users_total_non_negative.sql
├── analyses/
├── macros/
├── seeds/
└── snapshots/

La idea clave: los modelos de input_ports/, staging/ e intermediate/ son internos al producto de datos. Solo los modelos de output_ports/ forman la interfaz pública que consumen otros equipos. Los Output Ports están versionados (v1/, v2/, ...) y el contrato ODCS se guarda en el mismo directorio que el modelo SQL que lo implementa, así que el contrato vive junto al código que gobierna.

Mantenemos esta estructura como un conjunto de skills para coding agents en el plugin dataproduct-builder-dbt, de modo que Claude Code, Codex o Copilot CLI pueden generar el esqueleto de un proyecto nuevo, crear los modelos a partir de un Data Contract y sincronizarlo todo con Entropy Data.

Output Ports como modelos dbt

Los modelos de Output Port se implementan normalmente como vistas SQL o tablas materializadas que actúan como la API estable del producto de datos. Abstraen la lógica interna de staging y transformación y permiten cambiar la implementación sin afectar a los Data Consumers.

En lugar de escribir a mano las definiciones de los modelos dbt, la Data Contract CLI puede generarlas directamente a partir del Data Contract:

datacontract export dbt-models --output models/output_ports/v1/_models.yml models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml

Esto genera el YAML del modelo dbt con columnas, descripciones y tipos de datos:

# models/output_ports/v1/_models.yml (generated)

version: 2

models:
  - name: customer_activity
    description: Customer activity within Entropy Data for customer success.
    config:
      meta:
        data_contract:
          id: entropydata-customer-activity-v1
          file: models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml
        owner: customer-success
      materialized: table
      contract:
        enforced: true
    columns:
      - name: organization_id
        description: Unique identifier of the organization.
        data_type: STRING
        constraints:
          - type: not_null
          - type: unique
      - name: organization_vanity_url
        description: Vanity URL of the organization.
        data_type: STRING
      - name: organization_created_by
        description: Email address of the user that created the organization.
        data_type: STRING
      - name: organization_created_at
        description: Timestamp when the organization was created.
        data_type: TIMESTAMP
      - name: users_total
        description: Total number of users in the organization.
        data_type: BIGINT
        constraints:
          - type: not_null
      - name: users_added_30d
        description: Number of users added in the last 30 days.
        data_type: BIGINT
        constraints:
          - type: not_null
      - name: users_last_signed_up_at
        description: Timestamp when the last user signed up.
        data_type: TIMESTAMP
      - name: dataproducts_total
        description: Total number of data products in the organization.
        data_type: BIGINT
        constraints:
          - type: not_null
      - name: dataproducts_added_30d
        description: Number of data products added in the last 30 days.
        data_type: BIGINT
        constraints:
          - type: not_null
      - name: dataproducts_outputports_total
        description: Total number of output ports across all data products.
        data_type: BIGINT
        constraints:
          - type: not_null
      - name: dataproducts_outputports_with_datacontract_percentage
        description: Percentage of output ports that have an active data contract.
        data_type: DOUBLE
        constraints:
          - type: not_null
      - name: dataproducts_outputports_with_testresults_percentage
        description: Percentage of output ports that have test results.
        data_type: DOUBLE
        constraints:
          - type: not_null
      - name: dataproducts_last_updated_at
        description: Timestamp when the last data product was updated.
        data_type: TIMESTAMP
      - name: assets_total
        description: Total number of assets in the organization.
        data_type: BIGINT
        constraints:
          - type: not_null
      - name: data_platform
        description: The data contract / output port type used for most data products.
        data_type: STRING
      - name: updated_at
        description: Timestamp when this record was written by the dbt execution.
        data_type: TIMESTAMP
        constraints:
          - type: not_null
Generar el archivo del modelo dbt suele ser una operación puntual. A partir de ahí puedes guardar el modelo en Git y añadirle los detalles que necesites.

Ahora toca implementar la lógica de transformación SQL de cada modelo de salida:

-- models/output_ports/v1/customer_activity.sql
-- Governed by entropydata-customer-activity-v1.odcs.yaml (ODCS id: entropydata-customer-activity-v1)

{{ config(
    materialized='table',
    schema='op_v1'
) }}

select
    organization_id,
    organization_vanity_url,
    organization_created_by,
    organization_created_at,
    users_total,
    users_added_30d,
    users_last_signed_up_at,
    dataproducts_total,
    dataproducts_added_30d,
    dataproducts_outputports_total,
    dataproducts_outputports_with_datacontract_percentage,
    dataproducts_outputports_with_testresults_percentage,
    dataproducts_last_updated_at,
    assets_total,
    data_platform
from {{ ref('int_customer_activity') }}

Input Ports

Un producto de datos suele consumir datos de sistemas operacionales o de otros productos de datos. En el nuestro usamos datos extraídos con dlt desde nuestra base de datos operacional Postgres hacia un producto de datos en bruto, alineado con la fuente, en la plataforma de datos (Databricks).

En dbt, las entradas se modelan como sources. Cada Data Contract activo que consumimos se convierte en un archivo dentro de models/input_ports/, con el nombre del id del Output Port del proveedor. Junto a él cacheamos el contrato ODCS del proveedor upstream como instantánea de confianza, así git log muestra cuándo cambió por debajo un esquema o una regla de calidad upstream:

# models/input_ports/op_entropydata_postgres.source.yaml

version: 2

sources:
  - name: dp_entropydata_postgres_op_entropydata_postgres
    description: Operational database of the Entropy Data platform, extracted to Databricks via dlt.
    database: entropy_data_prod
    schema: entropydata_postgres
    config:
      meta:
        data_contract:
          id: entropydata-postgres-v1
          file: models/input_ports/op_entropydata_postgres.odcs.yaml
    tables:
      - name: organization
      - name: organization_member
      - name: data_product
      - name: asset

El sources[].name combina <provider-data-product-id>_<provider-output-port-id> para que dos acuerdos con el mismo proveedor pero distintos Output Ports nunca colisionen. El op_entropydata_postgres.odcs.yaml cacheado se guarda junto al archivo de source y se actualiza volviendo a ejecutar entropy-data datacontracts get, nunca a mano.

Transformación

Entre la entrada y la salida, los modelos internos hacen el trabajo de transformación con la lógica de negocio. No se exponen a los Data Consumers.

Los modelos de staging limpian y normalizan los datos brutos de origen: deduplican quedándose con la última versión, convierten tipos y renombran columnas.

-- models/staging/stg_organizations.sql

with source as (
    select *,
        row_number() over (partition by organization_id order by version desc) as _row_num
    from {{ source('dp_entropydata_postgres_op_entropydata_postgres', 'organization') }}
)

select
    organization_id,
    vanity_url as organization_vanity_url,
    created_by as organization_created_by,
    cast(created_at as timestamp) as organization_created_at
from source
where _row_num = 1
-- models/staging/stg_members.sql

with source as (
    select *,
        row_number() over (partition by organization_member_id order by version desc) as _row_num
    from {{ source('dp_entropydata_postgres_op_entropydata_postgres', 'organization_member') }}
)

select
    organization_member_id,
    organization_id,
    user_id,
    role,
    cast(created_at as timestamp) as created_at
from source
where _row_num = 1
-- models/staging/stg_data_products.sql

with source as (
    select *,
        row_number() over (partition by data_product_id order by version desc) as _row_num
    from {{ source('dp_entropydata_postgres_op_entropydata_postgres', 'data_product') }}
)

select
    data_product_id,
    organization_id,
    name,
    status,
    specification_type,
    cast(created_at as timestamp) as created_at,
    cast(updated_at as timestamp) as updated_at
from source
where _row_num = 1

Los modelos intermediate aplican la lógica de negocio: unen tablas, enriquecen con datos maestros y calculan campos derivados.

-- models/intermediate/int_customer_activity.sql

with members_per_org as (
    select
        organization_id,
        count(*) as users_total,
        count(case when created_at >= date_sub(current_date(), 30) then 1 end) as users_added_30d,
        max(created_at) as users_last_signed_up_at
    from {{ ref('stg_members') }}
    group by organization_id
),

data_products_per_org as (
    select
        organization_id,
        count(*) as dataproducts_total,
        count(case when created_at >= date_sub(current_date(), 30) then 1 end) as dataproducts_added_30d,
        -- TODO: add output_port source table to compute these metrics
        cast(0 as bigint) as dataproducts_outputports_total,
        cast(0 as double) as dataproducts_outputports_with_datacontract_percentage,
        cast(0 as double) as dataproducts_outputports_with_testresults_percentage,
        max(updated_at) as dataproducts_last_updated_at,
        first(specification_type) as data_platform
    from {{ ref('stg_data_products') }}
    group by organization_id
),

assets_per_org as (
    select
        organization_id,
        count(*) as assets_total
    from {{ ref('stg_assets') }}
    group by organization_id
)

select
    o.organization_id,
    o.organization_vanity_url,
    o.organization_created_by,
    o.organization_created_at,
    coalesce(m.users_total, 0) as users_total,
    coalesce(m.users_added_30d, 0) as users_added_30d,
    m.users_last_signed_up_at,
    coalesce(dp.dataproducts_total, 0) as dataproducts_total,
    coalesce(dp.dataproducts_added_30d, 0) as dataproducts_added_30d,
    coalesce(dp.dataproducts_outputports_total, 0) as dataproducts_outputports_total,
    coalesce(dp.dataproducts_outputports_with_datacontract_percentage, 0) as dataproducts_outputports_with_datacontract_percentage,
    coalesce(dp.dataproducts_outputports_with_testresults_percentage, 0) as dataproducts_outputports_with_testresults_percentage,
    dp.dataproducts_last_updated_at,
    coalesce(a.assets_total, 0) as assets_total,
    dp.data_platform
from {{ ref('stg_organizations') }} o
left join members_per_org m on o.organization_id = m.organization_id
left join data_products_per_org dp on o.organization_id = dp.organization_id
left join assets_per_org a on o.organization_id = a.organization_id

Construir el producto de datos

Cuando ejecutamos dbt run, dbt materializa todos los modelos y crea la tabla de salida en Databricks. El resultado es una tabla customer_activity en el esquema dp_entropydata_customer_activity_op_v1, lista para que la consuma el equipo de customer success.

La tabla customer_activity materializada en Databricks, con columnas como organization_id, organization_vanity_url y users_total.

Testing

El testing es lo que convierte un proyecto dbt en un producto de datos fiable. Sin tests, los Data Consumers no tienen motivos para confiar en los datos: se montarán sus propias comprobaciones, duplicarán lógica o directamente evitarán usar el producto de datos. Los tests automáticos hacen visible la calidad y dan a los Data Consumers la confianza de que los datos de los que dependen son correctos y completos.

Testear un producto de datos funciona en dos niveles: tests unitarios que verifican la implementación interna y tests de contrato que verifican la salida desde el punto de vista del Data Consumer.

Tests unitarios

Los tests de dbt verifican pasos concretos a lo largo del pipeline de datos. Están muy acoplados a la implementación y cambian según evolucionan los modelos dbt.

Los tests de esquema se declaran en los archivos YAML y validan not_null, unique, accepted_values y relationships en cada modelo. Los tests de datos personalizados son consultas SQL en la carpeta tests/ que comprueban reglas de negocio:

-- tests/assert_users_total_non_negative.sql

select organization_id
from {{ ref('customer_activity') }}
where users_total < 0

Si la consulta devuelve alguna fila, el test falla. Además, los contracts de dbt (desde dbt 1.5) fuerzan los nombres de columna y los tipos de datos en tiempo de build. El modelo dbt generado ya incluye contract.enforced: true.

Tests de contrato

La Data Contract CLI testea el Output Port desde el punto de vista del Data Consumer, contra el Data Contract. Es un test de aceptación: se conecta a la plataforma de datos real, consulta las tablas de salida y comprueba el esquema, el número de filas y las reglas de calidad definidas en el contrato.

datacontract test models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml
Resultados de tests de la Data Contract CLI con las comprobaciones de esquema y calidad de un producto de datos de clientes

Los tests de contrato son más estables que los tests de dbt. No cambian cuando refactorizas los modelos internos de staging o intermediate. Mientras el Output Port siga cumpliendo el contrato, los tests pasan. Eso los hace ideales para los pipelines de CI/CD y para generar confianza en los Data Consumers.

Data lineage con OpenLineage

El wrapper de dbt de OpenLineage (dbt-ol) emite eventos de data lineage al final de cada ejecución de dbt. Entropy Data los ingiere y dibuja un grafo interactivo de data lineage en la página del producto de datos, mostrando cómo las tablas de entrada en bruto fluyen por los modelos de staging, intermediate y de salida.

Configura el transporte en un openlineage.yml en la raíz del proyecto, codificando los identificadores del producto de datos y del Output Port como parámetros de consulta en el endpoint:

# openlineage.yml

transport:
  type: http
  url: https://api.entropy-data.com
  endpoint: api/v1/lineage?dataProductId=dp_entropydata_customer_activity&outputPortId=customer_activity
  auth:
    type: api_key

La apiKey se omite del archivo a propósito (no admite plantillas con variables de entorno) y se inyecta en tiempo de ejecución mediante OPENLINEAGE__TRANSPORT__AUTH__APIKEY, así el secreto nunca acaba en el control de versiones.

Pipeline de CI/CD

Cada producto de datos tiene su propio pipeline de CI/CD, que se ejecuta en cada push y de forma periódica:

  1. dbt-ol run materializa todos los modelos y emite eventos OpenLineage a Entropy Data
  2. dbt test ejecuta todos los tests de esquema y los tests de datos personalizados
  3. Se publican el producto de datos y el Data Contract en Entropy Data
  4. datacontract test ejecuta los tests de contrato contra el Output Port

Para esto usamos un workflow de GitHub Actions:

# .github/workflows/data-product.yml

name: Customer Activity Data Product
on:
  push:
    branches: [main]
  schedule:
    - cron: "0 6 * * *"

env:
  API: https://api.entropy-data.com/api
  DBT_DATABRICKS_HOST: ${{ secrets.DBT_DATABRICKS_HOST }}
  DBT_DATABRICKS_HTTP_PATH: ${{ secrets.DBT_DATABRICKS_HTTP_PATH }}
  DBT_DATABRICKS_TOKEN: ${{ secrets.DBT_DATABRICKS_TOKEN }}
  DATACONTRACT_DATABRICKS_TOKEN: ${{ secrets.DBT_DATABRICKS_TOKEN }}
  DATACONTRACT_DATABRICKS_SERVER_HOSTNAME: ${{ secrets.DBT_DATABRICKS_HOST }}
  DATACONTRACT_DATABRICKS_HTTP_PATH: ${{ secrets.DBT_DATABRICKS_HTTP_PATH }}

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install dependencies
        run: pip install dbt-databricks openlineage-dbt datacontract-cli[databricks] entropy-data

      - name: Create profiles.yml
        run: |
          mkdir -p ~/.dbt
          cat > ~/.dbt/profiles.yml <<EOF
          dp_entropydata_customer_activity:
            target: prod
            outputs:
              prod:
                type: databricks
                catalog: entropy_data_prod
                schema: dp_entropydata_customer_activity
                host: ${DBT_DATABRICKS_HOST}
                http_path: ${DBT_DATABRICKS_HTTP_PATH}
                token: ${DBT_DATABRICKS_TOKEN}
                threads: 4
          EOF

      - name: dbt deps
        run: dbt deps

      - name: dbt run
        run: dbt-ol run --target prod
        env:
          OPENLINEAGE__TRANSPORT__AUTH__APIKEY: ${{ secrets.ENTROPY_DATA_API_KEY }}

      - name: dbt test
        run: dbt test --target prod

      - name: Publish data product
        run: entropy-data dataproducts put dp_entropydata_customer_activity --file dp_entropydata_customer_activity.odps.yaml
        env:
          ENTROPY_DATA_API_KEY: ${{ secrets.ENTROPY_DATA_API_KEY }}

      - name: Publish data contract
        run: entropy-data datacontracts put entropydata-customer-activity-v1 --file models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml
        env:
          ENTROPY_DATA_API_KEY: ${{ secrets.ENTROPY_DATA_API_KEY }}

      - name: Data contract test
        run: |
          datacontract test models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml \
            --server production \
            --publish $API/test-results
        env:
          ENTROPY_DATA_API_KEY: ${{ secrets.ENTROPY_DATA_API_KEY }}

dbt-ol run materializa los modelos y envía los eventos OpenLineage a Entropy Data; dbt test ejecuta los tests unitarios. Después se publican los metadatos del producto de datos y del Data Contract con la CLI entropy-data, que envuelve la API REST de la plataforma y lee la API key de la variable de entorno ENTROPY_DATA_API_KEY. Por último, datacontract test valida el Output Port desde la perspectiva del Data Consumer.

Entropy Data

Entropy Data es un marketplace de productos de datos que gestiona productos de datos, Data Contracts y solicitudes de acceso. Se integra sin fricción para ofrecer una experiencia completa de producto de datos:

  • Descubrimiento: los Data Consumers exploran y encuentran productos de datos en un marketplace self-service
  • Gestión de accesos: los Data Consumers solicitan acceso y las aprobaciones pueden disparar el aprovisionamiento RBAC en la plataforma de datos
  • Gobernanza: seguimiento de la propiedad, la calidad y el data lineage en todos los productos de datos

Así se ve nuestro producto de datos Customer Activity en el marketplace de Entropy Data:

El producto de datos Customer Activity en el marketplace de Entropy Data, con el flujo de datos, los Output Ports, los fundamentos y el registro de auditoría.

Usa el Data Product Builder para implementarlo con coding agents

Toda la estructura descrita en este artículo (la organización del proyecto dbt, los contratos de Input Port y Output Port, el workflow de CI, la publicación de data lineage y de resultados de tests) se puede generar automáticamente con el Data Product Builder.

Empieza por un Data Contract. Pásaselo a Claude Code, OpenAI Codex o GitHub Copilot CLI. El agente genera exactamente este proyecto dbt, rellena los modelos, prepara los tests, configura el workflow de despliegue y cablea la integración con Entropy Data. La estructura sigue siendo personalizable: si prefieres Airflow en lugar de GitHub Actions, o convenciones de nombres distintas, haz un fork de la plantilla y el agente usará tu fork.

Esta página explica qué produce ese esqueleto, cómo encaja cada pieza y cómo ampliarlo con las convenciones de tu organización.

Valor de negocio

Con este producto de datos en marcha, nuestro equipo de customer success (que en realidad son nuestros co-founders...) puede consultar la tabla customer_activity directamente en Databricks para entender el nivel de actividad de cada cliente: cuántos usuarios tiene, si está añadiendo productos de datos de forma activa y qué plataforma de datos usa. Eso permite contactar de forma proactiva con los clientes que están creciendo, detectar pronto las cuentas inactivas y priorizar el soporte con datos. Sirve además de apoyo a las actividades de CRM y alimenta agentes de IA que identifican de forma proactiva dónde podemos ayudar a los clientes a construir mejores productos de datos o a montar integraciones.

El Data Contract garantiza el esquema y la calidad, así que pueden construir dashboards, agentes y automatizaciones encima con total confianza.

Regístrate gratis ahora o explora la demo interactiva de Entropy Data.