Catalog PyPI
PACKAGE EXPLORERView in registry

abl-db

PyPI

Un motor de base de datos tabular ligero, cifrado y ultrarrápido escrito en C con interfaz para Python.

Versions collected1
Direct dependencies0From release 0.1.1
Last observed20 Oct, 17:28 UTC

README

Version 0.1.1 documentation

🗃️ ABL — Array-Based Lightweight Database

Motor de base de datos tabular embebido en C con API Python ultrarrápida.

PyPI Python License Downloads Build

Persistencia estructurada sin servidores. Un solo archivo .abl, una clave secreta, y listo.


🚀 Instalación en 10 segundos

pip install abl-db

Requisito: Python 3.7+ y un compilador C (GCC/Clang/MSVC). La extensión C se compila automáticamente durante la instalación.


✨ ¿Por qué ABL?

CaracterísticaABLSQLitePostgreSQLJSON
Sin servidor✅✅❌✅
Esquemas tabulares✅✅✅❌
Ofuscación integrada✅❌❌❌
Motor en C nativo✅✅✅❌
Peso ligero✅✅❌✅
Zero-config✅✅❌✅

ABL llena el hueco entre JSON (sin estructura) y SQLite (overkill para proyectos pequeños). Ideal para scripts, herramientas CLI, microservicios y prototipos que necesitan persistencia tabular con un mínimo de fricción.


🎯 Uso en 30 segundos

from abl import ABLDatabase

# 1. Abre o crea la base de datos (un solo archivo .abl)
with ABLDatabase("datos.abl", secret="mi_clave") as db:

    # 2. Define una tabla con columnas
    productos = db.table("productos")
    productos.cols(["id", "nombre", "precio", "stock"])

    # 3. Inserta filas como diccionarios
    productos.set("001", {
        "id": "001",
        "nombre": "Laptop Pro",
        "precio": "1299.99",
        "stock": "42"
    })

    # 4. Recupera filas como diccionarios
    fila = productos.get("001")
    print(fila)
    # {'id': '001', 'nombre': 'Laptop Pro', 'precio': '1299.99', 'stock': '42'}

📖 Documentación completa

📦 Instalación

Desde PyPI (recomendado)

pip install abl-db

Desde el código fuente

git clone https://github.com/tu-usuario/abl-db.git
cd abl-db
pip install -e .

Verifica la instalación

from abl import ABLDatabase
print("✅ ABL instalado correctamente")

🏗️ Conceptos clave

ABL organiza los datos en tablas con filas identificadas por un row_id único. Cada fila es un diccionario donde las claves son las columnas definidas.

Base de datos (.abl)
├── Tabla: productos
│   ├── Esquema: ["id", "nombre", "precio", "stock"]
│   ├── Fila "001": {"id":"001", "nombre":"Laptop", ...}
│   └── Fila "002": {"id":"002", "nombre":"Monitor", ...}
│
└── Tabla: clientes
    ├── Esquema: ["id", "empresa", "email"]
    ├── Fila "C-01": {"id":"C-01", "empresa":"TechCorp", ...}
    └── Fila "C-02": {"id":"C-02", "empresa":"DevStudio", ...}

💡 Nota: El esquema de cada tabla se guarda automáticamente en la base de datos, así que no necesitas redefinirlo cada vez que abras el archivo.


🔧 API Reference

ABLDatabase(filename, secret)

Abre o crea una base de datos ABL.

ParámetroTipoDefaultDescripción
filenamestr"database.abl"Ruta del archivo .abl
secretstr"default_secret"Clave de ofuscación XOR (máx. 64 caracteres)
db = ABLDatabase("mi_db.abl", secret="supersecreto123")

Métodos:

MétodoRetornoDescripción
table(name)ABLTableObtiene o crea una tabla por nombre
keys()List[str]Lista todas las claves indexadas (filas + esquemas)
close()NoneCierra la BD y persiste los índices en disco

Context manager:

with ABLDatabase("datos.abl", secret="clave") as db:
    # ... operaciones ...
# Se cierra automáticamente al salir del bloque

ABLTable

Representa una tabla dentro de la base de datos.

tabla = db.table("nombre_tabla")

Métodos:

MétodoParámetrosDescripción
cols(columns)List[str]Define las columnas del esquema. Obligatorio antes de insertar.
set(row_id, data)str, Dict[str, Any]Inserta o actualiza una fila
get(row_id, buffer_size=4096)str, intRecupera una fila como diccionario
# Definir esquema
tabla.cols(["id", "nombre", "email"])

# Insertar / actualizar
tabla.set("USR-001", {
    "id": "USR-001",
    "nombre": "Ana López",
    "email": "ana@ejemplo.com"
})

# Recuperar
fila = tabla.get("USR-001")
# {'id': 'USR-001', 'nombre': 'Ana López', 'email': 'ana@ejemplo.com'}

Excepciones

ExcepciónHerenciaCuándo ocurre
ABLErrorExceptionError genérico del motor (fallo de E/S, sin memoria, etc.)
KeyNotFoundErrorABLError, KeyErrorLa fila o clave solicitada no existe
from abl import ABLDatabase, KeyNotFoundError

db = ABLDatabase("datos.abl", secret="clave")
tabla = db.table("usuarios")
tabla.cols(["id", "nombre"])

try:
    fila = tabla.get("ID_INEXISTENTE")
except KeyNotFoundError:
    print("❌ Esa fila no existe")

💡 Ejemplos prácticos

📝 Ejemplo 1: Inventario de productos

from abl import ABLDatabase

with ABLDatabase("inventario.abl", secret="inv2024") as db:
    productos = db.table("productos")
    productos.cols(["sku", "nombre", "categoria", "precio", "stock"])

    # Añadir productos
    productos.set("LAP-001", {
        "sku": "LAP-001",
        "nombre": "MacBook Air M3",
        "categoria": "Portátiles",
        "precio": "1199.00",
        "stock": "25"
    })

    productos.set("MON-002", {
        "sku": "MON-002",
        "nombre": "Dell UltraSharp 27\"",
        "categoria": "Monitores",
        "precio": "499.99",
        "stock": "12"
    })

    # Consultar
    laptop = productos.get("LAP-001")
    print(f"📦 {laptop['nombre']} — Stock: {laptop['stock']} unidades")

    # Listar todas las claves
    print("\n📋 Claves registradas:")
    for k in db.keys():
        print(f"   • {k}")

Salida:

📦 MacBook Air M3 — Stock: 25 unidades

📋 Claves registradas:
   • __schema__productos
   • productos:LAP-001
   • productos:MON-002

👥 Ejemplo 2: Gestión de empleados y clientes (múltiples tablas)

from abl import ABLDatabase

with ABLDatabase("empresa.abl", secret="empresaSecreta") as db:

    # Tabla de empleados
    empleados = db.table("empleados")
    empleados.cols(["dni", "nombre", "departamento", "salario", "activo"])

    empleados.set("72839102F", {
        "dni": "72839102F",
        "nombre": "María García",
        "departamento": "Ingeniería",
        "salario": "45000",
        "activo": "true"
    })

    empleados.set("83920184G", {
        "dni": "83920184G",
        "nombre": "Carlos Ruiz",
        "departamento": "Ventas",
        "salario": "38000",
        "activo": "true"
    })

    # Tabla de clientes
    clientes = db.table("clientes")
    clientes.cols(["id", "empresa", "contacto", "telefono", "pais"])

    clientes.set("C-9921", {
        "id": "C-9921",
        "empresa": "TechCorp SL",
        "contacto": "Juan Pérez",
        "telefono": "+34 600 123 456",
        "pais": "España"
    })

    # Consultas cruzadas
    emp = empleados.get("72839102F")
    cli = clientes.get("C-9921")

    print(f"👤 {emp['nombre']} ({emp['departamento']})")
    print(f"🏢 Cliente: {cli['empresa']} — {cli['pais']}")

🔐 Ejemplo 3: Configuración segura con ofuscación

from abl import ABLDatabase

# Los datos se ofuscan automáticamente con la clave secreta
with ABLDatabase("config.abl", secret="MiClaveSuperSecreta2024!") as db:
    config = db.table("settings")
    config.cols(["clave", "valor"])

    config.set("api_key", {"clave": "api_key", "valor": "sk-live-abc123xyz"})
    config.set("db_password", {"clave": "db_password", "valor": "p@ssw0rd!"})

    # Los datos están ofuscados en disco, pero legibles en memoria
    api = config.get("api_key")
    print(f"🔑 API Key: {api['valor']}")

⚠️ Nota de seguridad: La ofuscación XOR protege contra lectura casual del archivo, pero no es cifrado criptográfico robusto. Para datos altamente sensibles, considera cifrar el archivo a nivel de sistema operativo.


🔄 Ejemplo 4: Actualización de filas existentes

from abl import ABLDatabase

with ABLDatabase("stock.abl", secret="stock") as db:
    items = db.table("items")
    items.cols(["sku", "nombre", "cantidad"])

    # Insertar
    items.set("ITEM-01", {"sku": "ITEM-01", "nombre": "Teclado", "cantidad": "10"})

    # Actualizar (sobrescribe la fila con el mismo row_id)
    items.set("ITEM-01", {"sku": "ITEM-01", "nombre": "Teclado Mecánico", "cantidad": "5"})

    actualizado = items.get("ITEM-01")
    print(actualizado)
    # {'sku': 'ITEM-01', 'nombre': 'Teclado Mecánico', 'cantidad': '5'}

📋 Límites y especificaciones técnicas

LímiteValorNotas
Índices iniciales1,000Auto-escalable ×2 cuando se alcanza el límite
Longitud máx. de clave (row_id)64 caracteresIncluye prefijo tabla:
Columnas por tabla32Definidas con cols()
Longitud máx. de celda256 caracteresPor columna individual
Tamaño máx. de fila4,096 bytes (default)Auto-escalable al doble si es necesario
Longitud máx. de clave secreta64 caracteresUsada para la ofuscación XOR

🏗️ Arquitectura interna

┌─────────────────────────────────────────────┐
│              ABLDatabase (Python)           │
│         ┌─────────────────────┐             │
│         │   ABLTable (Python) │             │
│         │  ┌───────────────┐  │             │
│         │  │ abl.c (Motor C)│  │             │
│         │  │ ┌───────────┐ │  │             │
│         │  │ │ archivo   │ │  │             │
│         │  │ │  .abl     │ │  │             │
│         │  │ │ [Datos    │ │  │             │
│         │  │ │  XOR]     │ │  │             │
│         │  │ │ [Índices] │ │  │             │
│         │  │ └───────────┘ │  │             │
│         │  └───────────────┘  │             │
│         └─────────────────────┘             │
└─────────────────────────────────────────────┘

Formato del archivo .abl (binario):

┌──────────────────────────────────────────────────────────────┐
│  [Bloques de datos ofuscados]                                │
│  Cada bloque = fila CSV cifrada con XOR (clave secreta)      │
├──────────────────────────────────────────────────────────────┤
│  [Tabla de índices en memoria]                               │
│  Array de: { key[64 bytes], offset(uint64), length(uint32) } │
├──────────────────────────────────────────────────────────────┤
│  count   (uint32)  → Número total de registros               │
│  offset  (uint64)  → Posición del inicio de la tabla índices │
└──────────────────────────────────────────────────────────────┘
  • Persistencia: Los índices se guardan automáticamente al cerrar la base de datos (close() o salir del with).
  • Recuperación: Al abrir un archivo .abl existente, los índices se cargan desde el final del archivo.
  • Ofuscación: Todos los datos se cifran/descifran con XOR usando la clave secreta. Sin la clave correcta, los datos son ilegibles.

🛠️ Troubleshooting

Error: No se pudo cargar el motor C

ABLSError: No se pudo cargar el motor C ('_abl_engine.so')

Solución: La extensión C no está compilada. Instala desde el código fuente:

git clone https://github.com/tu-usuario/abl-db.git
cd abl-db
python setup.py build_ext --inplace
pip install -e .

Asegúrate de tener GCC instalado:


Error: Fila no encontrada (KeyNotFoundError)

KeyNotFoundError: Fila 'XYZ' no encontrada.

Causas comunes:

  1. El row_id no existe en la tabla.
  2. Intentas acceder a una fila de otra tabla (los IDs incluyen el prefijo tabla: internamente).
  3. La base de datos se abrió con una clave secreta diferente a la usada para escribir los datos.

Los datos aparecen como basura / caracteres extraños

Causa: La base de datos se abrió con una clave secreta diferente a la que se usó para escribir.

Solución: Asegúrate de usar exactamente la misma clave:

# Escritura
with ABLDatabase("datos.abl", secret="clave_correcta") as db:
    ...

# Lectura (debe ser la MISMA clave)
with ABLDatabase("datos.abl", secret="clave_correcta") as db:
    ...

📁 Estructura del paquete

abl/
├── __init__.py       # Exporta ABLDatabase, ABLError, KeyNotFoundError
├── core.py           # API Python + bindings ctypes al motor C
├── exceptions.py     # Jerarquía de excepciones
├── abl.c             # Motor principal en C (ofuscación, E/S, índices)
├── abl.h             # Headers y estructuras del motor
└── _abl_engine.so    # Extensión compilada (generada automáticamente)

setup.py              # Configuración de setuptools + Extension C
README.md             # Este archivo
LICENSE               # Licencia MIT

🤝 Contribuir

¡Las contribuciones son bienvenidas! Sigue estos pasos:

  1. Fork el repositorio
  2. Crea una rama: git checkout -b feature/nueva-funcionalidad
  3. Commitea tus cambios: git commit -am 'Añade nueva funcionalidad'
  4. Push: git push origin feature/nueva-funcionalidad
  5. Abre un Pull Request

Reportar bugs

Abre un issue en GitHub con:

  • Versión de Python (python --version)
  • Sistema operativo
  • Comando o código que reproduce el error
  • Traceback completo del error

ABL — Persistencia tabular sin fronteras. 🚀

⭐ Star en GitHub · 📦 PyPI · 🐛 Reportar bug

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.117 Aug 20260

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
aminbena010-ai/abl

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 17:28 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:02c5206b05787b2cd5f3c56a2b88f7a7696a6b57722952f01182a6f54847c97a