Skip to main content

DKOps

Gobierno de tablas Delta y orquestación de pipelines Spark, en local y en Databricks.

PyPI Python PySpark Delta Lake Docs License: MIT

Documentación · Primeros pasos · Demos · Changelog


DKOps es un framework en Python para construir lakehouses Delta con la arquitectura Medallion (Landing, Bronze, Silver y Gold). Describes tus tablas y tus cargas en archivos JSON versionados, y el framework se encarga de crearlas, validarlas, llenarlas y mantenerlas. El mismo código corre en tu equipo y en Databricks.

Por qué

Cuando un equipo de datos pasa de unos cuantos scripts a decenas de tablas, aparecen siempre los mismos problemas. DKOps los aborda así:

Problema Cómo lo resuelve
El schema de cada tabla está escondido en el código Contratos JSON validados antes de cada escritura
Un cambio de columnas rompe la carga SafeMigrator y la opción merge_schema
Cada dataset repite la misma lógica de ingesta IngestionEngine con estrategias que se eligen en el contrato
El código de local y el de Databricks divergen Detección de runtime y placeholders por entorno
Nadie sabe qué corrió anoche ni cuántas filas movió Tabla de control operativo consultable con SQL

Instalación

# Desarrollo local, incluye PySpark y Delta
pip install "DKOps[local]"

# Desde tu equipo contra un cluster, con Databricks Connect
pip install "DKOps[databricks-connect]"

# Dentro de Databricks, donde Spark y Delta ya están instalados
pip install DKOps

El módulo se importa como DKOps, respetando mayúsculas: import dkops no funciona.

Si instalas desde un tag de git, usa v0.3.2 o posterior. Los tags v0.3.0 y v0.3.1 tienen problemas de empaquetado que no afectan a los paquetes de PyPI; los detalles están en la guía de instalación.

Un vistazo rápido

Ingesta de Landing a Silver

from DKOps.launcher import Launcher
from DKOps.ingestion.engine import IngestionEngine

Launcher("config/config.json")

engine = IngestionEngine.from_launcher(
    bronze_contracts_dir    = "ingestion/batch",
    streaming_contracts_dir = "ingestion/streaming",
    silver_contracts_dir    = "ingestion/silver",
    tables_base_dir         = ".",
    ops_path                = "/tmp/ops/control",
)

engine.ingest_bronze()     # de Landing a Bronze
engine.run_streaming()     # de Landing a Bronze en streaming
engine.promote_silver()    # de Bronze a Silver
engine.status()

Escritura y lectura gobernadas

from DKOps.table_governance import load_contract, TableWriter, TableReader, SafeMigrator

contract = load_contract("tables/silver/ventas_current.json")

writer = TableWriter(contract)
writer.overwrite(df)
writer.upsert(df_cambios, keys=["venta_id"])
writer.overwrite_partition(df_dia, {"fecha": "2024-01-15"})

reader = TableReader(contract)
df = reader.read(filter="estado = 'activo'")
cambios = reader.read_cdf(starting_version=1)

SafeMigrator(contract, dry_run=True).apply()   # muestra el plan sin ejecutar

Contratos

Toda la configuración vive en dos tipos de contrato JSON.

Contrato de tabla, en tables/{bronze,silver,gold}/. Describe cómo es la tabla:

{
  "catalog": "{catalog.silver}",
  "schema":  "ventas",
  "name":    "ventas_current",
  "columns": [
    { "name": "venta_id",   "type": "STRING",  "nullable": false },
    { "name": "email",      "type": "STRING",  "mask": "security.mask_email" },
    { "name": "is_deleted", "type": "BOOLEAN" }
  ],
  "partitions": ["canal"],
  "properties": { "change_data_feed": true }
}

Contrato de ingesta, en ingestion/{batch,streaming,silver}/. Describe cómo se llena:

{
  "name":                 "ventas_current",
  "strategy":             "cdc_merge",
  "source_contract":      "../../tables/bronze/ventas_raw.json",
  "destination_contract": "../../tables/silver/ventas_current.json",
  "merge_keys":           ["venta_id"],
  "watermark_col":        "fecha_venta"
}

Los placeholders {catalog.<capa>}, {path.<nombre>}, {env} y {env_short} se resuelven con el bloque environments de config.json, así el mismo contrato sirve para desarrollo y producción. Los JSON Schema de ambos tipos están en schema/ y se validan con python scripts/validate_contracts.py.

Estrategias de promoción a Silver

Estrategia Cuándo usarla
full_merge Catálogos y dimensiones que llegan completos en cada entrega
cdc_merge Eventos de cambio con op_type I/U/D; aplica borrado lógico con is_deleted
incremental_replace Snapshots diarios en los que solo cuenta la partición más reciente
append_dedup Eventos, logs o clickstream que nunca se actualizan

Idempotencia

Los pipelines se pueden ejecutar varias veces sin duplicar datos. Bronze sobrescribe la partición _ingested_date del día, Silver hace upsert por clave de negocio y el streaming guarda checkpoints.

Demos

El repositorio trae cinco proyectos completos, cada uno con su generador de datos:

Demo Dominio Lo más destacado
demo_1 Aeronáutica Los cinco writers y SafeMigrator
demo_2 Manufactura Reglas de calidad declarativas y transformaciones con tests
demo_3 E-commerce merge_schema, máscaras de columna y streaming
demo_4 Retail e inventario read_cdf(), read_stream() y SafeMigrator
demo_5 Marketplace Flujo completo hasta Gold con tabla de control
python demos/demo_5/pipeline.py

Los demos escriben en /tmp/dkops_demoN/. Borra esa carpeta si quieres empezar de cero.

Estructura del repositorio

src/DKOps/
├── launcher.py              SparkSession y detección de runtime
├── environment_config.py    catálogos, rutas y placeholders
├── logger_config.py         logging con Loguru
├── ingestion/               motor de ingesta, readers y estrategias
└── table_governance/        contratos, writers, reader y migraciones
schema/                      JSON Schema de los contratos
demos/                       cinco proyectos de ejemplo
docs/                        sitio de documentación (MkDocs)
tests/                       suite de pytest

Desarrollo

git clone https://github.com/brrsanchezfi/DKOps
cd DKOps
pip install -e ".[local]"

python -m pytest -q                       # tests unitarios
python -m pytest tests/integration -q     # integración con Spark y Delta reales

Los tests de integración deben correr en un proceso aparte: los tests unitarios sustituyen pyspark por un mock en sys.modules.

Para trabajar en la documentación:

pip install mkdocs-material "mkdocstrings[python]"
mkdocs serve

pyspark y databricks-connect no pueden convivir en el mismo entorno virtual. Si usas ambos, mantén dos entornos separados.

Licencia

MIT. Consulta el archivo LICENSE.

Release files for DKOps 0.3.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for DKOps 0.3.6
File Size Uploaded
dkops-0.3.6.tar.gz 89.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for DKOps 0.3.6
File Interpreter ABI Platform
dkops-0.3.6-py3-none-any.whl Python 3 none any Details

Total release size: 181.2 kB

Release files / dkops-0.3.6.tar.gz

Download URL dkops-0.3.6.tar.gz
Size 89.2 kB
Tags Source
SHA-256 checksum
How to use checksums
addb7cc6fa41a3968bee8113474f0e85903b57dea71b8e21ac0b3480e59091d1
BLAKE2b-256 checksum
How to use checksums
65f8ca339fcab46f029cf94e979d5251d8968b5fa83736f4fb4bdec44d538adc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.

Transparency log

Release files / dkops-0.3.6-py3-none-any.whl

Download URL dkops-0.3.6-py3-none-any.whl
Size 92.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a0ee44b1ff5ec0e45c91482568cc4313dd53dc504f554745869c35b91a83a0ad
BLAKE2b-256 checksum
How to use checksums
69e06d0df87098eccc9c39ba2d3618c60694e8c0ac19ad227945bfc4afa3884b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.6 This release

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page