programación SQLite

Sqlite: Rápido, ágil, liviano y robusto
Gerardo Antonio Cabero, Daniel Maldonado

Cada vez que los desarrolladores nos enfrentamos a nuevos desafíos, es primordial saber optar por la mejor herramienta para el tratamiento de los datos. Desde que en la informática se comenzó a trabajar con datos, la mayor preocupación e interrogante fue cómo manipular esos datos. Hasta hace algunas décadas atrás era un verdadero calvario para el desarrollador, puesto que el mantenimiento se realizaba a través del manejador de archivos del lenguaje con el cual se realizaba la implementación. Aquello desencadenó que surgieran las primeras alternativas para separar el programa del mantenimiento y manipulación de los datos. Fue así que surgieron los primeros motores que cumplían esa función; hoy podemos encontrar grandes titanes, como Oracle, Informix, PostgreSQL, MySQL y Firebird.

A

un así muchos desarrolladores han optado En su versión 3, SQLite permite base de datos de hasta 2 por una opción que surgió de la necesidad terabytes de tamaño y la inclusión de campos tipo blob (exde buscar agilidad, sencillez y sobre todo, traído de la Wikipedia). cero configuración. Su nombre es SQLite y ha llegado para quedarse... Breve Historia de SQLite Cuando D. Richard Hipp trabajaba desarrollando soft¿Qué es SQLite? ware para la fuerza naval de los Estados Unidos, comenSQLite es un proyecto de dominio público creado por D. Ri- zó a desarrollar SQLite , según él cuenta con sus propias chard Hipp que implementa una pequeña librería de aproxi- palabras: SQLite surgió de una necesidad personal, para madamente 500Kb programada en lenguaje C, que funciona mi propio uso. como un sistema de gestión de base de datos relacionales. En enero de 2000 yo estaba trabajando con un equiA diferencia de los motores de base de datos convencio- po de la General Dynamics en la Fuerza naval de los nales con la arquitectura cliente-servidor, SQLite es indepen- Estados Unidos, en un proyecto de software, el cual se diente, ya que no se comunica con un motor de base de datos, conectaba a una base de datos Informix, el motor funsino que las librerías de SQLite pasan a integrar la aplicación. cionaba muy bien, pero habíamos tenido problemas para La misma utiliza las funcionalidades de SQLite a través de hacer una reconfiguración cuando el sistema se reiniciallamadas simples a sub rutinas y funciones. Esto reduce la ba. Luego cambiamos a PostgreSQL, pero administrar latencia en el acceso a la base de datos, debido a que las lla- la base de datos era un problema. Si bien aún estaba madas a funciones son más eficientes que la comunicación luchando para hacer frente a estas cuestiones, surgió la entre procesos. El conjunto de la base de datos (definiciones, idea de escribir un simple motor de base de datos SQL tablas, índices, y los propios datos), son guardados como un que permitiera leer los archivos del disco duro, y luego solo fichero estándar, en la máquina local. ser llamados en diferentes solicitudes. Cinco meses más

2

linux@software.com.pl

Linux+ 9/2007

programación SQLite
tarde, yo estaba sin un contrato por algunos Razones para elegir SQLite unos meses y por lo que comencé a escribir Abajo están presentadas varias ventajas de SQLite, con el pensamiento de que sería útil SQLite que pueden ser de ayuda: en algún problema similar, más adelante. • (Extracto del Prólogo de SQLite escrito por • Tamaño: SQLite tiene una pequeña memoRichard Hipp). ria y una única biblioteca es necesaria para •
Listado 1. Creación de una nueva base de datos
$ sqlite3 prueba.db SQLite version 3.3.10 Enter ".help" for instructions ...> id smallint primary key, ...> nombre varchar(25), ...> apellido varchar(25), ...> direccion varchar(25) ...> ); sqlite> Estructura Sql : CREATE TABLE nombre (campo1 tipo, campo2 tipo, campo3 tipo,.., campoN tipo);

sqlite> CREATE TABLE personal (

Listado 2.XXXXXXXXXXXXXXXXXXXX
sqlite> .help .databases List names and files of attached databases .dump ?TABLE? ... Dump the database in an SQL text format .echo ON|OFF Turn command echo on or off .exit Exit this program .explain ON|OFF Turn output mode suitable for EXPLAIN on or off. .header(s) ON|OFF Turn display of headers on or off .help Show this message .import FILE TABLE Import data from FILE into TABLE .indices TABLE Show names of all indices on TABLE .mode MODE ?TABLE? Set output mode where MODE is one of: csv Comma-separated values column Left-aligned columns. (See .width) html HTML <table> code insert SQL insert statements for TABLE line One value per line list Values delimited by .separator string tabs Tab-separated values tcl TCL list elements .nullvalue STRING Print STRING in place of NULL values .output FILENAME Send output to FILENAME .output stdout Send output to the screen .quit Exit this program .prompt MAIN CONTINUE Replace the standard prompts .read FILENAME Execute SQL in FILENAME .schema ?TABLE? Show the CREATE statements .separator STRING Change separator used by output mode and .import .show Show the current values for various settings .tables ?PATTERN? List names of tables matching a LIKE pattern .timeout MS Try opening locked tables for MS milliseconds .width NUM NUM ... Set column widths for "column" mode sqlite>

acceder a bases de datos, lo que lo hace ideal para aplicaciones de bases de datos incorporadas Rendimiento de base de datos: SQLite realiza operaciones de manera eficiente y es más rápido que MySQL y PostgreSQL Portabilidad: SQLite se ejecuta en muchas plataformas y sus bases de datos pueden ser fácilmente portadas sin ninguna configuración o administración Estabilidad: SQLite es compatible con ACID, reunión de los cuatro criterios de Atomicidad, Consistencia, Aislamiento y Durabilidad SQL: SQLite implementa un gran subconjunto de la ANSI - 92 SQL estándar, incluyendo sub-consultas, generación de usuarios, vistas y triggers Interfaces: SQLite cuenta con diferentes interfaces del API, las cuales permiten trabajar con C++, PHP, Perl, Python, Tcl, groovy, etc. Costo: SQLite es de dominio público, y por tanto, es libre de utilizar para cualquier propósito sin costo y se puede redistribuir libremente.

Características de SQLite

SQLite goza de un par de características que lo hacen único, alguna de ellas se detallan a continuación.

Cero Configuración
De la forma en que fue concebido y diseñado SQLite, NO necesita ser instalado. No prender, reiniciar o apagar un servidor, e incluso configurarlo. Esta cualidad permite que no haya un administrador de base de datos para crear las tablas, vistas, asignar permisos. O bien la adopción de medidas de recuperación de servidor por cada caída del sistema.

Portabilidad
SQLite puede ser ejecutado en diferentes sistemas operativos, como ser Windows, Linux, BSD, Mac OS X, Solaris, HPUX,AIX o estar embebido en muchos otros como QNX, VxWorks, Symbian, Palm OS, Windows CE. Se pude notar que muchos de ellos trabajan a 16, 32 y 64 Bits. La portabilidad no está dada en sí por el software, sino por la base de datos condensada en un solo archivo, que puede estar situado en cualquier directorio, trayendo como ventaja que la base de datos puede ser fácilmente copiada a algún dispositivo USB o ser enviada vía correo electrónico. En cambio, los motores de base de datos tienden por lo general a almacenar la colección de archivos, al que sólo el motor de la base de da-

www.lpmagazine.org

3

programación SQLite
tos puede llegar a tener acceso. Esto hace que los datos sean más seguros y más difíciles de acceder. Algunos proporcionan la opción de escribir directamente en el disco y pasar por el sistema de ficheros todos juntos. Esto aporta un mayor rendimiento, pero a costa de una considerable complejidad de instalación y mantenimiento. disco necesario para almacenar la información real del campo. Tomando el ejemplo anterior, si quisiera almacenar un solo carácter en un campo definido como VARCHAR(100), entonces un único byte de espacio de disco se consume. Realmente una característica especial para ahorrar espacio en memoria. El uso de registros de longitud variable por SQLite, tiene una serie de ventajas, entre ellas el resultado de un pequeño archivo de base de datos y optimización de la velocidad de la misma, puesto que hay menos información desperdiciada que leer y recorrer. utilizados. Pero estos motores se siguen rigiendo por la ley de derechos de autor. SQLite es diferente ya que en el derecho de autor la ley simplemente no se aplica, todos pueden contribuir, modificar, estudiar y compartir libremente SQLite.

Registros de longitud variable
Generalmente los motores asignan una cantidad fija de espacio en disco para cada fila en la mayoría de los campos de una determinada tabla. Por ejemplo, tomemos un campo de tipo VARCHAR(100), esto significa que el motor le asignará 100 bytes de espacio fijo en disco, independientemente de la cantidad de información que se almacene en ese campo. En cambio, SQLite realizará todo lo contrario, utilizando para ello la cantidad de espacio en
Listado 3.XXXXXXXXXXXXXXXXXXXXX
sqlite> .mode list sqlite> SELECT * FROM personal; 1|Juan|Perez|YYYXXXZZZ 2|Ramon|Gomez|ZZZXXXYYY sqlite>

Limitaciones
Una vez escuché decir que no existía un software al cual no se le encontraran limitaciones. SQLite no está exento de esto, algunas de las limitaciones son las siguientes: • Limitaciones en Where: esta limitación está dada por el soporte para clausuras anidadas. Falta de Clave Foránea: se hace caso omiso de las claves foráneas; esto quiere decir, cuando se realice la creación de la tabla desde el modo consola, está permitiendo el uso de la clausura, aunque no realizara el chequeo de la misma. Falta de documentación en español: al momento de escribir este artículo es muy escasa la documentación disponible en español sobre SQLite.

Pedagógico
Algunas veces cuando se está en un ámbito educativo, se tiende a enseñar SQL para administrar las bases de datos. Muchas veces transportar una base a casa no es tarea fácil, por eso SQLite está siendo adoptado de una forma pedagógica. Por ejemplo, los estudiantes pueden enviar vía e-mail las bases de datos a los docentes para su presentación y los docentes realizarán las observaciones necesarias. Para los estudiantes más avanzados que están interesados en el estudio de cómo trabaja un RDBMS, el código SQLite puede servir como una buena base. Esto no quiere decir que es un modelo exacto de la forma en que los motores de bases de datos se apliquen, sino una forma en la que un estudiante que entiende cómo funciona SQLite puede comprender los principios operativos de otros sistemas.

Listado 4.XXXXXXXXXXXXXXXXXXXXX
sqlite> .separator ", " sqlite> SELECT * FROM personal; 1, Juan, Perez, YYYXXXZZZ 2, Ramon, Gomez, ZZZXXXYYY sqlite>

Introducción al uso de SQLite

La arquitectura SQLite
Cada motor de base de datos compila cada sentencia SQL en algún tipo de estructura de datos interna que luego se utilizará para llevar a cabo la labor de la declaración. En SQLite, compilar la forma de las declaraciones es un breve programa en un lenguaje de máquina como representación. Los usuarios podemos ver la máquina virtual antes poniendo EXPLAIN como palabra clave para una consulta. El uso de la VM dentro de SQLite ha sido un gran beneficio para el desarrollo de la biblioteca, ya que proporciona un cruce entre la interfaz de usuario que analiza las sentencias SQL y la parte en la cual la máquina virtual ejecuta el código para calcular el resultado, así también utilizar la capacidad de rastreo de la ejecución de la VM en cada sentencia e imprimir las mismas.

Listado 5.XXXXXXXXXXXXXXXXXXXXX
sqlite> .mode line sqlite> SELECT * FROM personal; id = 1 nombre = Juan apellido = Perez direccion = YYYXXXZZZ id = 2 nombre = Ramon apellido = Gomez direccion = ZZZXXXYYY sqlite>

SQLite, al igual que muchos de los motores de bases de datos, posee su administración predefinida a través del uso de la consola o terminal, aquellas personas que pudieron administrar antes otros motores como por ejemplo es el caso de MySQL, sabrán que no es el único administrador que se conoce sino más bien existen una amplia gama para la elección, por ejemplo phpMyAdmin. Con SQLite sucede lo mismo: es posible administrarlo desde varios sistemas, como es el caso de phpSQLiteAdmin, Visual SQLite, realSqlserver.

Listado 6.XXXXXXXXXXXXXXX
sqlite> .mode column sqlite> SELECT * FROM personal; 1 Juan Perez YYYXXXZZZ 2 Ramon Gomez ZZZXXXYYY sqlite>

Licencia de Dominio Público
SQLite se encuentra bajo esta licencia, por ende ninguna reivindicación se hace de los derechos de autor en cualquier parte del núcleo del código fuente. Existen otros motores de bases de datos basados en SQL liberados de licencias que permiten al código ser amplia y libremente Figura 1. Esquema de SQLite

4

Linux+ 9/2007

programación SQLite

Cómo instalar SQLite

capsula en un sólo archivo que vamos a crear Su instalación se pude realizar por medio de (Listado 1). Como habrán podido observar en el los repositorios o a través de su fuente, como ejemplo, una vez creado el archivo prueba.db observaremos a continuación. (de ahora en adelante nuestra base de datos) y con la ayuda del lenguaje SQL, hemos creado A través de los repositorios una tabla llamada personal con cuatro campos Como ya es costumbre, si tenemos nuestra (id, nombre, apellido, dirección). Podemos obdistribución predilecta y contamos con acceso servar que la forma de escritura es más cómoda, a Internet o tenemos los DVD de repositorios puesto que podemos escribir de manera prolija y contamos con los permisos de super usuario el armado de una tabla, con los delimitadores en root, tipeamos lo siguiente: sentencia “,” y el fin de la misma a través del limitador”;”. Ahora realizaremos la inserción de aptitude install sqlite3 algunos datos para el ejemplo que hemos creado de la siguiente manera: Si contamos con los códigos fuentes descargados desde el sitio oficial de SQLite http: sqlite> INSERT INTO personal //www.sqlite.org/download.html, simplemente VALUES(1, 'Juan', 'Perez', deberemos realizar los siguientes pasos: 'YYYXXXZZZ'); • Descomprimimos los fuentes de SQLite en alguna carpeta con tar xzf
sqlite.tar.gz sqlite> INSERT INTO personal VALUES(2, 'Ramon', 'Gomez', 'ZZZXXXYYY');

sqlite> Estructura en SQL: SELECT Campo1, Campo2,.., Campo4 FROM Tabla ;

La consulta realizada anteriormente lista todos los campos y todos los registros de la tabla personal, pero es posible listar únicamente los campos que deseamos que aparezcan en la consulta. Para ello los separamos por medio del “,” y además podemos agregarle la cláusula WHERE para poder filtrar registros que cumplan con una determinada condición, por ejemplo:
sqlite> SELECT id, nombre, apellido FROM personal WHERE id <= 2; 1|Juan|Perez 2|Ramon|Gomez sqlite>

• •

Ejecutamos el script ./configure Estructura en SQL: Ejecutamos make install para realizar la instalación en el sistema INSERT INTO TABLA
VALUES(val1,val2,val3,.., valn);

Si deseamos instalar SQLite en el sistema operativo Windows, la instalación se realizará de la siguiente forma: descargamos los ejecutables de SQLite, usamos la consola de línea de comandos de Windows cmd, nos posicionamos en la carpeta y ejecutamos el archivo sqlite3.exe, el cual disparará la consola de sqlite3.

Una vez vistas estas operaciones básicas como son la creación de una base de datos, la creación de una tabla, agregación de datos a la tabla y realización de consultas, es posible que queramos salir del editor o administrador de SQLite para lo cual tipeamos lo siguiente:
sqlite> .quit

Primeros pasos con SQLite

Nuevamente observemos la inserción de los datos con la sentencia INSERT de SQL, haciendo referencia a la tabla y posteriormente los valores para el nuevo registro. Seguramente en algún momento vamos a contar con la necesidad de realizar consultas sobre las tablas creadas. Para este fin podemos realizarlo de la siguiente manera:

Una vez que hemos instalado SQLite en nuestro sistema, nos posicionaremos en algún directorio sqlite> SELECT * vacío y realizaremos la creación de una nueva FROM personal; base de datos. Recordemos que él, a diferencia 1|Juan|Perez|YYYXXXZZZ de los otros motores de bases de datos, se en- 2|Ramon|Gomez|ZZZXXXYYY

Figura 2. Creación de la Base de Datos en consola

Figura 3. Inserción en tablas desde consola

Ahora bien, aprendamos algunos comandos especiales para movernos sobre SQLite en modo texto, ya que de esta manera nos vamos a poder mover con mayor facilidad, seguridad y rapidez. La mayoría de las veces SQLite lee las líneas de entrada y las transforma a las de la librería SQLite para luego ejecutarlas. Si una línea de entrada empieza con un punto ("."), es interpretado inmediatamente por el intérprete de SQLite. Estos puntos se utilizan normalmente para cambiar el formato de salida de la consulta, la cual veremos más adelante. Para obtener una lista de los comandos disponibles, podemos tipear en cualquier momento .help o ayuda y nos arrojará la lista que podemos ver en el listado 2. Realicemos una introducción para poder manipular las salidas o configurarlas. Cabe destacar que SQLite3 es capaz de mostrar los resultados de una consulta en ocho diferentes formatos entre los cuales tenemos: csv, column, html, insert, line, tabs, y tcl. Puedes usar .mode o modo, para lograr estas diferentes salidas. La modalidad por defecto es en la cual SQLite nos muestra los datos tras una consulta realizada previamente. Esta consulta estándar es separada por este símbolo: "|". Para acceder a la base de datos creada anteriormente, tipeamos lo siguiente: $ sqlite3 prueba.db

www.lpmagazine.org

5

programación SQLite
Una vez dentro de la misma, podemos realizar lo que presenta el listado 3. Ahora bien si utilizas .separator va a cambiar el modo de separación de la consulta, por ejemplo lo vamos a hacer cambiar por una coma y un espacio "," (Listado 4). En el modo line o línea, cada columna de un registro de la base de datos se muestra en una línea por sí mismo. Cada línea está formada por el nombre de la columna, el signo igual "=" y el dato correspondiente. Ahora el separar los registros se realiza por una línea en blanco (Listado 5). En el modo column o columna, cada registro se muestra con una línea separada con los datos alineados en las columnas, miremos el ejemplo presentado en el listado 6. Vemos que por defecto cada columna posee un ancho de 10 caracteres, donde los datos que quizás sean demasiado grandes se pueden truncar o recortar. Afortunadamente para ello podemos ajustar el ancho de la columna con .width como en el siguiente ejemplo:
sqlite> .width 12 6

en donde los valores que se coloquen allí son totalmente correspondientes a la columna de la consulta que se va a realizar. El 12 significa que el espacio será de 12 caracteres, 6 es para la columna de apellido y así podemos continuar con los demás. Las etiquetas o nombre de cada columna que aparecen de manera de referencia pueden activarse y desactivarse mediante .header con los valores ON y OFF. Si tomamos el ejemplo anterior podemos verlo mejor en el Listado 7. El modo de salida, que quizás sea muy útil, es el modo insert o insertar. En este modo la salida se formatea para que parezca un INSERT de SQL. Al especificar este nuevo modo, tienes que dar un argumento extra que es
Listado 7.XXXXXXXXXXXXXXXXXXXX
sqlite> .header on sqlite> SELECT * FROM personal; id nombre apellido direccion ------------ ------ ---------- --------1 Juan Perez YYYXXXZZZ 2 Ramon Gomez ZZZXXXYYY sqlite>

el nombre de la tabla en la cual se incluirán estos INSERT. Lo vemos mas claro en el ejemplo mostrado en el Listado 8. Para finalizar tenemos el modo html. En este modo SQLite3 escribe los resultados de la consulta en una tabla XHTML, utilizando las famosas y conocidas etiquetas HTML (Listado 9). Por defecto SQLite3 envía los resultados de una determinada consulta a la salida estándar que es seguramente la terminal o Konsole que utilizas para realizar estas pruebas. Es posible cambiar estas salidas usando el comando .output. Simplemente hay que colocar el archivo de salida como argumento de .output y todos los resultados de esa consulta serán escritos en ese archivo de salida. Si queremos que vuelva a la salida estándar: .output stdout . Mira el Listado 10. El programa SQLite3 viene con varios comandos que son útiles para analizar el esquema de la base de datos. No hay nada que hagan estos comandos que no pueda hacerse por otros medios. Estos comandos facilitan únicamente un atajo. Por ejemplo, para ver las tablas de nuestra base de datos .tables:
sqlite> .tables personal sqlite>

caso omiso de la misma dentro de su estructura. A pesar de ser considerado una librería, SQLite ha abierto un nuevo ENTORNO Y ENFOQUE al tratamiento de base de datos, pasó de ser una simple librería a un esquema mucho más amplio. Desde SQLite Latinoamérica, hemos llamado al mismo esquema como PseudoMotor, algo que aparenta ser un motor pero no lo es. Esto se debe a que contiene dentro de sí mismo muchas características de los grandes motores de base de datos, como ser: la creación de usuarios, vistas, triger, etc. Otra cualidad interesante que hemos expuesto desde la comunidad es la capacidad de poder definir la integridad referencial a través de los trigger, haciéndolo casi similar a un motor de base de datos, pero manteniendo la sencillez y simplicidad de una librería.

SQLite y los lenguajes de programación

En los siguientes párrafos mostraremos a través de algunos ejemplos cómo implementar SQLite para algunos de los lenguajes existentes y algunas cualidades de los mismos.

Sqlite y Java
Java implementa la conexión a la fuente de datos a través de las librerías JDBC. Desde hace algún tiempo se encuentran disponibles las SQLiteJDBC, en Zentus (www.zentus.com/ sqlitejdbc/). De allí podremos descargar los JDBC de SQLite para plataformas Linux, Mac OS, y Windows. Para poder trabajar con SQLite y Java debemos realizar una simple conexión. La realizaremos por medio de una clase la cual llamaremos coneccion. Debe contar con la estructura mostrada en el Listado 12.

En SQLite podemos realizar copias de seguridad de las tablas de nuestra base de datos, para ello vamos a ver un ejemplo. Simplemente hay que colocar el nombre del archivo con el argumento .output, luego el modo, en este caso .mode insert personal: para ver las sentencias de inserciones. .schema personal es el esquema de la tabla. Así al finalizar tenemos una copia de seguridad de las tablas de la base de datos (Listado 11). El detalle de los métodos El nombre de conector que se utilizará nos inSQLite: ser o no ser un motor dica Class.forName("org.sqlite.JDBC");, Ésta es la pregunta que todos deben realizarse en en nuestro caso: org.sqlite.jdbc . este punto. Muchos de los usuarios de software Aquí se indica el driver con que trabajarelibre y desarrolladores, al ver el funcionamiento mos jdbc: sqlite y el nombre de la base de de SQLite, afirman que es un motor de base de datos base.sql: datos, aunque en realidad no lo es, puesto que no posee la integridad referencial. En palabras más varConeccion = DriverManager. simples: la integridad referencial es el control de getConnection("jdbc:sqlite:" + la clave foránea. Si bien en SQLite, cuando se nombreDB); crea una tabla, se pude invocar a la palabra reservada forean key. Pero el compilador realizará El flujo para realizar las sentencias abre el siguiente comando:
varSentencia = this.varConeccion. createStatement();

Figura 4. Envío de una consulta

Hasta este punto sólo hemos realizado la conexión de la base de datos a través de la clase coneccion. A continuación conoceremos el

6

Linux+ 9/2007

programación SQLite
método más importante de la clase Statement En el Listado 13 está presentado el código de que es executeUpDate el cual permite enviar las recuperación de datos con Java y SQLite. consultas al motor. Su estructura es la siguiente: Se recorre todo el resulset y cada elemento-producto de las consultas, se deposita en la sentancia.executeUpdate instancia persona que es un objeto de la clase (Sentencia SQL) vector. Luego podremos listar todo el contenido del vector simplemente recorriéndolo y Si se desea crear una tabla se debería de llamar mostrando su contenido. a ese método con la consulta de la siguiente manera: SQLite y PHP En la versión 4 de PHP, SQLite se podía utilizar sentancia.executeUpdate(“CREATE como base de datos instalando un módulo PETABLE personal (id smallint CL. A partir de la versión 5 de PHP, SQLite está primary key, nombre incluido en PHP, por lo que está disponible sin varchar(25))”); necesidad de realizar ninguna instalación adicional, realmente una ventaja a la hora de prograAhora si se quiere recuperar datos de la tabla re- mar y se puede observar la gran aceptación de cién creada es necesario escribir un método que este pseudo motor. Los nombres de las funciones recupere objetos y objetos de la clase personal. de PHP que permiten utilizar y manipular SQLiListado 8.XXXXXXXXXXXXXX
sqlite> .mode insert nueva_tabla sqlite> SELECT * FROM personal; INSERT INTO nueva_tabla VALUES(1,'Juan','Perez','YYYXXXZZZ'); INSERT INTO nueva_tabla VALUES(2,'Ramon','Gomez','ZZZXXXYYY'); sqlite>

te en PHP empiezan por sqlite_ y son similares a los que permiten acceder a otras bases de datos utilizables desde PHP (MySQL, PostgreSQL, etc). El manual de PHP incluye un capítulo dedicado a SQLite, es por ello que nos va a permitir programar mas rápidamente y acostumbrarnos a la sintaxis de una forma casi inmediata.

Creación/Acceso a la base de datos
En SQLite, una base de datos es normalmente un fichero, aunque también pueden abrirse bases de datos en memoria. Este concepto ya lo vimos al principio. Por esta razón necesitamos un mecanismo para poder abrir la base de datos, la función es sqlite_open(). El argumento de sqlite_open() es la ruta del archivo en el servidor (o :memory: en el caso de crear la base de datos en memoria). En caso de que la base de datos no exista, la función se encarga de crear una base de datos nueva. La función devuelve un manejador (handle), que se utiliza en el resto de funciones que acceden a la base de datos. En el siguiente ejemplo, la variable $rutadb almacena la ruta o path de donde se encuentra la base de datos y la variable $db el manejador de la base de datos:
<?php $rutadb = "prueba.db"; $db = sqlite_open($rutadb) or die("No es posible abir la base de datos "); ?>

Listado 9.XXXXXXXXXXXXXXXXXX
<TABLE></TABLE>, <TR>, <TH> y <TD> sqlite> .mode html sqlite> SELECT * FROM personal; <TR><TH>id</TH><TH>nombre</TH><TH>apellido</TH><TH>direccion</TH></TR> <TR><TD>1</TD> <TD>Juan</TD> <TD>Perez</TD> <TD>YYYXXXZZZ</TD> </TR> <TR><TD>2</TD> <TD>Ramon</TD> <TD>Gomez</TD> <TD>ZZZXXXYYY</TD> </TR> sqlite>

Consultas a la base de datos

Una vez abierta la base de datos, se pueden realizar consultas del lenguaje SQL utilizando varias funciones. Cada función devuelve el resultado de la consulta de forma distinta: •
sqlite_array_query(handle, consulta, tipo): devuelve la consulta en forma de matriz sqlite_exec(consulta): devuelve simplemente verdadero o falso, pero no los datos sqlite_query(handle, consulta): devuelve un manejador del resultado sqlite_single_query(handle, consulta, primera_línea): devuelve únicamente una columna o la primera fila del resultado sqlite_unbuffered_query(handle, consulta): devuelve la consulta sin prefecht

• • •

Listado 10.XXXXXXXXXXXXXXXXXXXX
sqlite> .mode list sqlite> .separator | sqlite> .output archivo_salida_1.txt sqlite> SELECT * FROM personal; sqlite> .exi $ cat archivo_salida_1.txt 1|Danyx|Maldoando|YYYXXXZZZ 2|LaRepa|Web|ZZZXXXYYY $

La función sqlite_array_query() devuelve la respuesta de la consulta en forma de matriz. No es conveniente utilizar esta función si el resultado de la consulta contiene muchos registros, ya que puede ocupar mucha memoria en el servidor.

www.lpmagazine.org

7

programación SQLite Varias consultas
En estos ejemplos, la variable $db es un manejador creado con sqlite_open() como vimos anteriormente. Para crear una nueva tabla, se utiliza la consulta CREATE TABLE. Para crear un campo índice hay que definirlo INTEGER PRIMARY KEY, y los demás campos se crean colocando el nombre que va a llevar dicho campo y, si quisiéramos, qué tipo de datos va a contener. Para el ejemplo vamos a crear la tabla personal con los campos id, nombre y apellido:
<?php sqlite_query($db, "CREATE TABLE personal (id INTEGER PRIMARY KEY, nombre, apellido)"); ?>

<?php sqlite_query($db, "DROP TABLE personal"); ?> ?>

apellido = 'López' WHERE id = '4'");

Para borrar un registro de una tabla, se utiliza la Para añadir un registro a una tabla específica, se consulta DELETE FROM. Nuevamente debemos utiliza la consulta INSERT INTO: especificar cuál es el registro que deseamos <?php eliminar:
sqlite_query($db, "INSERT INTO personal VALUES (NULL , 'Marcelo' , 'Perez')" ); ?> ?> <?php sqlite_query($db, "DELETE FROM personas WHERE id = '1'");

Ahora bien si lo que deseamos es borrar una sqlite_query($db, "UPDATE tabla, utilizamos la consulta DROP TABLE: personal SET nombre = 'Juan',

Para modificar un registro de una tabla específica, se utiliza la consulta UPDATE. Es necesario Quizás, sí lo habrás notado, las consultas SQL identificar con la cláusula WHERE cuál es el son las mismas que implementamos siempre en registro que vamos a modificar: nuestras aplicaciones y son totalmente compatibles y válidas, lo único que varía son las funcio<?php nes que llamamos, propias de cada librería.

Integrar SQLite en Python

En primer lugar para poder integrar SQLite con Python necesitamos que en Python tengamos instaladas unas librerías que nos van a servir como interfaz para conectar las bases de datos SQLite. Para ello hacemos lo siguiente: $ sudo
apt-get install python-pysqlite2

Conexión con las bases de datos
Figura 5. Vista del .header en consola
Listado 11.XXXXXXXXXXXXXXXX
sqlite> .output backup.sql sqlite> .mode insert personal sqlite> .schema personal sqlite> SELECT * FROM personal; sqlite> .quit

Ahora ya estamos listos para poder comenzar a trabajar con pysqlite, en primer lugar debemos importar esta librería para poder hacer uso de la misma: >>> from pysqlite2 import dbapi2
as sqlite

Listado 12.XXXXXXXXXXXXXXXXXXXXXXXX
package pruebaBD; import org.sqlite.*; import java.sql.Connection; import java.sql.Statement; public class Coneccion {

Con esto ya podemos hacer uso de las librerías. Ahora lo que vamos a hacer es crear una nueva base de datos para poder trabajar sobre la misma. La conexión con la base de datos se realiza instanciando un objeto y enviando como parámetro el archivo, en caso que el archivo o la base de datos no exista hay que encargarse de crearla y en caso que esté creada sólo abrirla: >>> conexion = sqlite
.connect('prueba.db')

private Connection varConeccion; private Statement varSentencia; public Coneccion(){

Una vez que tengamos la conexión realizada, debemos crear un objeto cursor, ésto se realiza llamando al método cursor de nuestro objeto: >>> cursor = conexion.cursor()

Escribiendo datos con Python
Una vez realizada la conexión, ya estamos dispuestos a crear y guardar datos en nuestra base de datos. Para hacer esto debemos ejecutar un método de nuestro cursor llamado execute pasándole como parámetro nuestra consulta. En este primer ejemplo vamos a crear una Tabla:

Class.forName("org.sqlite.JDBC");

varConeccion = DriverManager.getConnection("jdbc:sqlite:" + “base.sql”); varSentencia = varConeccion.createStatement(); } }

8

Linux+ 9/2007

programación SQLite
Ahora que ya tenemos creada nuestra tabla, podemos comenzar a cargarle información, nuevamente convocando el método execute de nuestro objeto cursor:
>>> cursor.execute('INSERT INTO personal VALUES (null, "Ramos", "Juan", "juan_85@gmail.com")') >>> cursor.execute('INSERT INTO personal VALUES (null, "Juarez", "Martin", "martin58j@gmail.com")')

>>> cursor.execute('CREATE TABLE personal (id INTEGER PRIMARY KEY, apellido

VARCHAR(50), nombre VARCHAR(50), email VARCHAR(100))')

Figura 6. Salida del formato Html desde consola
Listado 13.XXXXXXXXXXXXXXXXXX
public personal traertodos() { Vector persona = new Vector(); Resulset rs; rs = this.sentencia.executeQuery("SELECT * FROM personal"); while (rs.next()) { } rs.close(); } } return personal; persona.add(personal(rs.getInt("id"), rs.getString("Nombre")));

Estos ejemplos son a modo de visualizar el modo en el cual se pueden almacenar datos en nuestra base de datos. La librería pysqlite nos permite almacenar datos de otra manera utilizando variables que por ejemplo hemos recuperado de algún Form o Widget:
>>> apellido = "Gomes" >>> nombre = "Carlos" >>> email = "gcarlos@yahoo.com" >>> cursor.execute('INSERT INTO personal VALUES (null, ?, ?, ?)', (apellido, nombre, email))

Listado 14.XXXXXXXXXXXXXXXXXXXXXXX
>>> cursor.execute('SELECT * FROM personal') >>> for fila in cursor: print 'ID: ', fila[0]

print 'Apellido: ', fila[1] print 'Nombre: ', fila[2] print 'Email: ', fila[3] print '-'*10 ID: 1 Apellido: Ramos Nombre: Juan Email: juan_85@gmail.com ---------ID: 2 Apellido: Juarez Nombre: Martin Email: martin58j@gmail.com ---------ID: 3 Apellido: Gomes Nombre: Carlos Email: gcarlos@yahoo.com ----------

Una vez que terminamos de hacer los cambios, debemos almacenar estos datos de manera permanente invocando al método commit de nuestro objeto conexion: >>> conexion.commit() Si intentas cerrar una conexión que ha sido modificada sin invocar al método commit, pysqlite plantea un error. Este comportamiento puede causar problemas, sin embargo si ustedes no desean guardar los cambios que se han efectuado pueden convocar al método rollback de nuestro objeto conexion: >>>
conexion.rollback()

Recuperando datos con Python
Ahora que tenemos datos almacenados en nuestra base de datos, podemos recuperarlos nuevamente invocando el método execute de nuestro objeto cursor y haciendo uso del comando SELECT. Vamos a obtener todos los valores de la tabla:
>>> cursor.execute('SELECT * FROM personal')

El cursor ahora tiene todos los datos de la tabla personal. Existen varias maneras de recuperar esos datos. La primera es utilizando el método fetchall(), el cual nos imprime una lista con todos los elementos de la siguiente manera:

www.lpmagazine.org

9

programación SQLite
mentación. En este artículo hemos visto unas opciones de SQLite que tiene la potencia de un motor, condensado en una librería o PseudoMotor. Se pueden observar algunas claras ventajas, como lo es la presencia de las extensiones, para casi todos los lenguajes que existen. Cuando Daniel y yo pusimos a prueba SQLite, lo realizamos frente a los colosos del software libre MySQL y PostgreSQL. Notamos que SQLite es muy rápido en respuesta cuando se realizan las consultas y el manejo de los datos. Esto se debe a que no existe un proceso intermedio para la comunicación con el motor. Cosa que sí realizan los ya mencionados motores. Algunos puntos fuertes fueron la carencia de configuraciones y el tener una base de datos en un solo archivo. No obstante, hay que aclarar que SQLite tiene algunos puntos flacos como ser que no es apropiado para realizar aplicaciones cliente/servidor o para implementaciones de gran escala, como puede ser un padrón electoral. Puesto que SQLite se saturaría con las peticiones de los usuarios. Por tal motivo se recomienda el uso para aplicaciones de mediana complejidad. Otro punto a favor que está teniendo, y por ello muchos han optado por migrar a SQLite, está dado en que empresas como Google, han anunciado públicamente la utilización de SQLite en su producto AdSense. Otros claros ejemplos son Philips que utiliza SQLite en el software de alguno sus electrodomésticos y la empresa Symbian que lo ha definido como estándar de base de datos para su sistema operativo. Con respecto a la comunidad de SQLite Latinoamericana invitamos a todos aquellos que se quieran sumar a este proyecto: las puertas se encuentran abiertas.

>>> cursor.execute ('SELECT * FROM personal') >>> print cursor.fetchall() [(1, "Ramos", "Juan", "juan_85@gmail.com"), (2, "Juarez", "Martin", "martin58j@gmail.com"), (3, "Gomes", "Carlos", "gcarlos@yahoo.com")]

>>> cursor.techone() (1, "Ramos", "Juan", "juan_ 85@gmail.com") next(),

Creo que es un método muy simple para ver el contenido por medio de tuplas, pero quizás los datos no tengan un formato adecuado. Para ello existe una forma también muy sencilla a través del uso de los iteradores (Listado 14). También podemos hacer uso del método fetchone(), el cual sólo obtiene una fila del cursor, pero no en forma de lista sino como una tupla. Es útil para cuando nosotros sólo deseamos ver una única fila o quizás una fila Conclusión a la vez: Día a día se avanza a pasos agigantados en el desarrollo, pero siempre existe ese >>> cursor.execute desafío que hace al desarrollador definir la ('SELECT * FROM herramienta que ha de utilizar para realizar personal') el manejo de los datos dentro de su imple-

Contamos también con el método similar al fetchone() en el sentido en que devuelven una única fila. Sin embargo con este método hay que tener cuidado ya que debemos tener un control del recorrido de los datos. Si es que sobrepasamos el límite es posible que nos devuelva un error (Listado 15). Nuevamente podemos ver la excelente integración de SQLite con Python, un lenguaje interpretado y orientado totalmente a objetos. Pysqlite, la biblioteca integradora que permite armar una interfaz muy simple para hacer uso de la misma. Utilizando este tipo de motor de base de datos, como es SQLite, podemos lograr aplicaciones móviles de manera muy segura y confiable.

Figura 7. Muestra los resultados de aplicar esta forma de backup
Listado 15.XXXXXXXXXXXXXXXXXXXXXX
>>> cursor.execute('SELECT * FROM personal') >>> cursor.next() (1, "Ramos", "Juan", "juan_85@gmail.com") >>> cursor.next() (2, "Juarez", "Martin", "martin58j@gmail.com") >>> cursor.next() (3, "Gomes", "Carlos", "gcarlos@yahoo.com") >>> cursor.next() Traceback (most recent call last): File "<pyshell#201>", line 1, in -toplevelcursor.next() StopIteration

Sobre los Autores
Gerardo Antonio Cabero y Daniel Maldonado son argentinos oriundos de las provincias de Salta y Jujuy. Son administradores y miembros fundadores de la comunidad de SQLite latinoamérica. Ambos se desempeñan como consultores informáticos en sus respectivas provincias. Más información en: cabero@gmail.com daniregede@hotmail.com sqlite-latino.blogspot.com www.larepaweb.com.ar

10

Linux+ 9/2007

Sign up to vote on this title
UsefulNot useful