Gestión de datos

Python y Btrieve 2 en Windows: Acceso a datos Zen con NoSQL

Corporación Actian

2 de febrero de 2018

Conectar ServiceNow a los datos de otras aplicaciones no tiene por qué ser difícil

En mi blog anterior ("Programming the Easy Way: Accediendo a una base de datos PSQL Zen con Python y ODBC"), mostré cómo acceder fácilmente a una base de datos Actian Zen con Python y ODBC. Mi siguiente proyecto era utilizar la nueva función Btrieve 2 con Python para interactuar directamente con los archivos de datos sin utilizar ningún SQL.

Los antiguos clientes de Btrieve/PSQL/Zen están familiarizados con la antigua función Btrieve, una interfaz de programación 3GL clásica que no ha cambiado realmente en más de 30 años. Proporciona acceso directo al motor para que pueda manipular archivos de datos con opciones como Crear, Abrir, Insertar, Actualizar, Eliminar, GetFirst, GetNext, GetEqual, etc. Ahora, con Actian Zen v13 disponemos de Btrieve 2, que ofrece una interfaz orientada a objetos simplificada y más intuitiva que cubre todo el conjunto de llamadas de Btrieve al motor de base de datos. Esta interfaz se proporciona para desarrolladores C/C++, pero también suministramos archivos SWIG (Simplified Wrapper & Interface Generator) para que la interfaz pueda ser utilizada por desarrolladores Python, Perl y PHP.

La configuración para utilizar Btrieve 2 con Python requiere unos pocos pasos:

  1. Prepare su entorno Windows:
    • Instalar el motor de base de datos Actian Zen v13
    • Instalar Python para Windows - He utilizado v3.6 64-bit de python.org
    • Descargar y descomprimir Swig para Windows - He utilizado Swigwin-3.0.12 de swig.org
    • Descargue y descomprima el SDK de Btrieve 2
    • También se requiere Visual Studio 2015 o posterior; puedes instalar una versión Community de Microsoft si aún no la tienes desde aquí.
  2. Cree una carpeta MyPrograms para su código Python y copie los siguientes archivos del SDK de Btrieve 2:
    • btrieveCpp.lib & btrieveC.lib de win64
    • btrieveC.h & btrieveCpp.h de include
    • btrievePython.swig & btrieveSwig.swig de swig
  3. Abra un símbolo del sistema, vaya a la carpeta MyPrograms e introduzca el siguiente comando:
    <swigwin_location>swig -c++ -D_WIN64 -python btrievePython.swig
    Esto crea los siguientes archivos: btrievePython.py & btrievePython_wrap.cxx
  4. Crea un archivo de texto en MisProgramas llamado setup.py que contenga lo siguiente:
    from distutils.core import setup, Extension
    btrievePython_module = Extension('_btrievePython', sources=['btrievePython_wrap.cxx'],
         library_dirs=['<MyPrograms location>'], libraries=['btrieveCpp'],  )
    setup (name='btrievePython', version='1.0', author='Actian',
         description="""Compile Btrieve 2 Python module""",
         ext_modules=[btrievePython_module], py_modules=["btrievePython"], )
  5. En un símbolo del sistema, en la carpeta MyPrograms, ejecute este comando para construir el módulo btrievePython:
    python setup.py build_ext --plat-name="win-amd64"
    Esto crea el archivo Python compilado buildlib.win-amd64-3.6_btrievePython.cp36-win_amd64.pyd
  6. Cambie el nombre del archivo .pyd por _btrievePython.pyd y cópielo en MisProgramas o en la carpeta DLLs de su instalación de Python.

Una vez completados estos pasos, debería poder "importar btrievePython" en un entorno o programa Python.

Una vez configurada la biblioteca de importación btrievePython, ¡ya está listo para escribir aplicaciones Btrieve 2 en Python! He aquí un ejemplo que realiza las mismas operaciones de base de datos que la versión ODBC de mi blog anterior: crear el mismo archivo, insertar registros y recuperar el recuento total insertado. Este código es aproximadamente el doble de largo que la versión ODBC, pero accede al fichero directamente sin pasar por la capa SQL. (Nota - sólo se ha incluido una mínima comprobación de errores):

import os
import sys
import struct
import btrievePython as btrv

btrieveFileName = "Test_Table.mkd"
recordFormat = "<iB32sBBBH"
recordLength = 42
keyFormat = "<i"

# Create a session:
btrieveClient = btrv.BtrieveClient(0x4232, 0) # ServiceAgent=B2

# Specify FileAttributes for the new file:
btrieveFileAttributes = btrv.BtrieveFileAttributes()
rc = btrieveFileAttributes.SetFixedRecordLength(recordLength)
# Specify Key 0 as an autoinc:
btrieveKeySegment = btrv.BtrieveKeySegment()
rc = btrieveKeySegment.SetField(0, 4, btrv.Btrieve.DATA_TYPE_AUTOINCREMENT)
btrieveIndexAttributes = btrv.BtrieveIndexAttributes()
rc = btrieveIndexAttributes.AddKeySegment(btrieveKeySegment)
rc = btrieveIndexAttributes.SetDuplicateMode(False)
rc = btrieveIndexAttributes.SetModifiable(True)

# Create the file:
rc = btrieveClient.FileCreate(btrieveFileAttributes, btrieveIndexAttributes,
btrieveFileName, btrv.Btrieve.CREATE_MODE_OVERWRITE)
if (rc == btrv.Btrieve.STATUS_CODE_NO_ERROR):
     print('nFile "' + btrieveFileName + '" created successfully!')
else:
     print('nFile "' + btrieveFileName + '" not created; error: ', rc)

# Allocate a file object:
btrieveFile = btrv.BtrieveFile()
# Open the file:
rc = btrieveClient.FileOpen(btrieveFile, btrieveFileName, None, btrv.Btrieve.OPEN_MODE_NORMAL)
if (rc == btrv.Btrieve.STATUS_CODE_NO_ERROR):
     print('File open successful!n')
else:
     print('File open failed - status: ', rc, 'n')

# Insert records:
iinserting = True
while iinserting:
     new_name = input('Insert name (Q to quit): ' )
     if new_name.lower() == 'q':
          iinserting = False
     else:
          record = struct.pack(recordFormat, 0, 0, new_name.ljust(32).encode('UTF-8'), 0, 22, 1, 2018)
          rc = btrieveFile.RecordCreate(record)
          if (rc == btrv.Btrieve.STATUS_CODE_NO_ERROR):
               print(' Insert successful!')
          else:
               print(' Insert failed - status: ', rc)

# Get Record count:
btrieveFileInfo = btrv.BtrieveFileInformation()
rc = btrv.BtrieveFile.GetInformation(btrieveFile, btrieveFileInfo)
print('nTotal Records inserted =', btrieveFileInfo.GetRecordCount())

# Close the file:
rc = btrieveClient.FileClose(btrieveFile)
if (rc == btrv.Btrieve.STATUS_CODE_NO_ERROR):
     print('File closed successful!')
else:
     print('File close failed - status: ', rc)

Dado que el ejemplo anterior no hace ninguna lectura de datos, volví atrás y añadí un poco más de código antes de cerrar el archivo para demostrar un escaneo de archivo que busca un nombre:

# Buscar registro por nombre
ireading = True
while ireading:
     encontrar_nombre = input('nEncontrar nombre (Q para salir): ' )
     if nombre_encontrado.lower() == 'q':
          ireading = False
     else
          foundOne = False
          record = struct.pack(recordFormat, 0, 0, ' '.ljust(32).encode('UTF-8'), 0, 0, 0, 0)
          readLength = btrieveFile.RecordRetrieveFirst(btrv.Btrieve.INDEX_NONE, registro, 0)
          while (readLength > 0):
               recordUnpacked = struct.unpack(recordFormat, record)
               if (recordUnpacked[2] == find_name.ljust(32).encode('UTF-8')):
                    print(' Registro coincidente encontrado: ID:', recordUnpacked[0], ' Nombre:', recordUnpacked[2].decode())
                    foundOne = True
               readLength = btrieveFile.RecordRetrieveNext(record, 0)
          if (foundOne == False):
               print(' No se ha encontrado ningún registro que coincida con "'+nombre_encontrado+'"')
          status = btrieveFile.GetLastStatusCode()
          if (status != btrv.Btrieve.STATUS_CODE_END_OF_FILE):
               print(' Error de lectura: ', status, btrv.Btrieve.StatusCodeToString(status))

La sencillez de la programación en Python, combinada con la nueva interfaz de desarrollo Btrieve 2, permitirá la rápida creación de nuevas aplicaciones Zen.

Si tiene alguna pregunta sobre Zen u otros productos Actian, no dude en preguntar en los foros de nuestra comunidad.

logo avatar actian

Acerca de Actian Corporation

Actian hace que los datos sean fáciles. Nuestra plataforma de datos simplifica el modo en que las personas conectan, gestionan y analizan los datos en entornos en la nube, híbridos y locales. Con décadas de experiencia en gestión de datos y análisis, Actian ofrece soluciones de alto rendimiento que permiten a las empresas tomar decisiones basadas en datos. Actian cuenta con el reconocimiento de los principales analistas y ha recibido premios del sector por su rendimiento e innovación. Nuestros equipos comparten casos de uso probados en conferencias (por ejemplo, Strata Data) y contribuyen a proyectos de código abierto. En el blog de Actian, tratamos temas que van desde la ingesta de datos en tiempo real hasta el análisis basado en IA. Conozca al equipo directivo https://www.actian.com/company/leadership-team/