Tus datos cambiaron.
¿Qué versión les toca?

Compara dos versiones de un dataset. Obtén el salto que merecen y la entrada de changelog que lo explica.

$ pip install datasemver
Inicio rápido
Terminal ejecutando datasemver diff sobre dos ficheros CSV. Un panel indica un salto sugerido MAJOR, de 0.0.0 a 1.0.0. Una tabla compara el tipo, la proporción de nulos y la cardinalidad de cada columna, una segunda tabla clasifica siete cambios por severidad, y la entrada de changelog generada cierra la ejecución.
Lee
CSV, JSON, Parquet, SQL
Python
3.10 a 3.14
Reglas por defecto
20
Tests
534 al 99%
Licencia
Apache 2.0

El código tiene SemVer. Los datos no.

Una columna eliminada, un teléfono que se convirtió en cadena, una distribución que se desplazó en silencio. Todo eso rompe a quien está aguas abajo. Y todo eso suele publicarse como «se actualizó el dataset».

DataSemver hace ese impacto explícito y revisable, para que publicar un dataset se pueda discutir como se discute publicar una librería.

Cómo decide

Cada diferencia se contrasta contra una regla, y cada regla lleva una severidad. La severidad más alta encontrada se convierte en el salto, y por eso el orden de abajo es el argumento entero y no una forma de agrupar tres tarjetas.

major

Las consultas existentes pueden romperse

Algo de lo que ya dependen los consumidores ha desaparecido, o ahora significa otra cosa.

  • column_removed
  • type_changed_incompatible
  • column_renamed
  • distribution_shift
  • psi_greater_than
minor

Información nueva, los contratos se mantienen

Hay más de lo que había, y nada de lo que estaba se ha movido.

  • column_added
  • row_count_increased
  • new_category_added
  • cardinality_changed
  • category_balance_shift
  • rows_modified
patch

El mismo significado, mejores datos

El dataset dice lo que ya decía, con menos huecos o menos ruido.

  • nulls_fixed
  • minor_stat_change
  • type_changed_compatible

La severidad es de tu fichero de reglas, no del cambio en sí. Las reglas por defecto son una opinión; a su lado viajan perfiles estricto y permisivo, y el catálogo de reglas (en inglés) lista cada regla, métrica y umbral. Lo que ninguna regla cubre se reporta como no clasificado y nunca infla el resultado.

El delimitador se detecta, no se supone

Esta exportación separa sus campos con punto y coma mientras cada importe lleva además una coma. La coma nunca llega a la cabecera, así que gana el punto y coma y el fichero se carga como cinco columnas en lugar de una.

Se reconocen coma, punto y coma, tabulador y barra vertical. Define DATASEMVER_CSV_DELIMITER para saltarte la detección por completo.

Terminal ejecutando datasemver diff sobre dos CSV separados por punto y coma. Las columnas se dividen correctamente en id, cliente, pais, importe y estado, se reporta una columna canal añadida, y la ejecución termina con un salto MINOR de 1.4.2 a 1.5.0.

El mismo análisis en el navegador

El panel es un cliente de la librería, no una copia bifurcada. Llama a la misma función y pinta el mismo informe, así que los dos coinciden por construcción.

El panel web de DataSemver tras comparar dos versiones de un dataset de clientes. Una insignia MAJOR aparece junto a 1.4.2 a 2.0.0, unos indicadores muestran de 40 a 48 filas, de 8 a 8 columnas y 6 cambios, y una tabla lista cada cambio con su severidad, su regla y su descripción.

Sube dos ficheros, o elige dos versiones de un directorio que vigile.

Compara distribuciones, no solo esquemas

Una media es un punto de una distribución, y una columna puede reconstruirse a su alrededor sin moverla. Tres cambios que rompen a cualquier consumidor aguas abajo, y que una comparación de esquemas y promedios reporta como nada en absoluto:

Una forma, no un centro

La dispersión se multiplica por cuarenta y la media no se mueve. Se mide con un estadístico de Kolmogorov-Smirnov sobre una rejilla de cuantiles guardada.

std 0.998 → 39.96

Un balance, no un conjunto

Una etiqueta pasa de equilibrada a una entre cien con ambos valores todavía presentes, así que el conjunto de categorías no cambia. Se mide con el Population Stability Index.

'ok' 50.3% → 99.0%

Una ventana en el tiempo

Una columna de fecha se compara por dónde se sitúa de verdad, así que un export que se ha deslizado o que ahora cubre medio periodo es un cambio y no un silencio.

2020-01-01 → 2026-01-01

Ambas se pesan contra lo que la muestra puede sostener. Un estadístico KS no tiene una lectura fija: con cuatro filas contra cinco, añadir una sola mueve la distribución un quinto, así que un desplazamiento tiene que superar el valor crítico para esos tamaños además del umbral configurado. Con un puñado de filas no se reporta nada, porque no hay nada que reportar. Y con --key las filas se emparejan en lugar de resumirse: una versión donde se ha reescrito un tercio de ellas con valores de la misma distribución tiene el mismo perfil que la anterior, y es un dataset distinto para quien haga un join.

El perfil sobrevive a los datos

Una comparación lee un perfil: las columnas, sus tipos, sus ratios de nulos, una rejilla de cuantiles y los conteos por categoría. Es lo bastante pequeño para guardarlo junto al dataset, y entonces la versión anterior no hay que descargarla nunca — ni que exista.

Dataset
63,6 MB
Su perfil
2,9 KB
Ratio
21.916:1
# escríbelo una vez, junto a los datos
datasemver profile customers_v3.parquet

# compara contra él más adelante, con el fichero ya desaparecido
datasemver diff customers_v3.profile.json customers_v4.parquet

Cinco formas de usarlo, un informe

Línea de comandos

Construida sobre typer y rich. Añade --json cuando quien lee la respuesta es un script y no una persona.

datasemver diff old.csv new.csv

Tablas de base de datos

Una URL de conexión con la tabla tras #. SQLite no necesita driver; PostgreSQL y MySQL usan el extra sql.

sqlite:///snapshots.db#clientes

Librería de Python

Dos rutas, o dos perfiles que ya tengas en memoria cuando los datos vienen de una consulta al almacén.

from datasemver import analyze

Panel web

Una herramienta local, sin autenticación y sin límite de peticiones. Mantenla en la interfaz de loopback.

pip install "datasemver[web]"

GitHub Action

Analiza los datasets que toca un pull request y publica el salto sugerido, reescribiendo el mismo comentario en cada push. Define un umbral y rechaza el merge — después de comentar, para que el rechazo llegue con su motivo.

scripts/run_datasemver_on_pr.py
# leer el salto desde un script de release
BUMP=$(datasemver diff old.csv new.csv --json | jq -r '.bump')

# anteponer la entrada de changelog a un fichero que tú mantienes
datasemver diff old.csv new.csv --current-version "$(cat VERSION)" --output CHANGELOG.md

# rechazar un cambio que rompe: 0 salió limpio, 1 fue rechazado, 2 no pudo ejecutarse
datasemver diff old.csv new.csv --fail-on major

# qué filas cambiaron, no solo si cambió la forma
datasemver diff old.csv new.csv --key id

Instalarlo

Python 3.10 o superior, tipado y sin acceso a red en tiempo de ejecución. Las releases se publican desde CI mediante Trusted Publishing con procedencia firmada, así que no existe ningún token de larga duración.

$ pip install datasemver
Verlo en PyPI