Está en la página 1de 9

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
linux@software.com.pl

por una opción que surgió de la necesidad terabytes de tamaño y la inclusión de campos tipo blob (ex-
de 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, comen-
SQLite 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 equi-
A 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 fun-
sino 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 reinicia-
llamadas 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+ 9/2007
programación
SQLite

tarde, yo estaba sin un contrato por algunos Razones para elegir SQLite acceder a bases de datos, lo que lo hace
unos meses y por lo que comencé a escribir Abajo están presentadas varias ventajas de ideal para aplicaciones de bases de datos
SQLite, con el pensamiento de que sería útil SQLite que pueden ser de ayuda: incorporadas
en algún problema similar, más adelante. • Rendimiento de base de datos: SQLite
(Extracto del Prólogo de SQLite escrito por • Tamaño: SQLite tiene una pequeña memo- realiza operaciones de manera eficiente y
Richard Hipp). ria y una única biblioteca es necesaria para es más rápido que MySQL y PostgreSQL
• Portabilidad: SQLite se ejecuta en muchas
Listado 1. Creación de una nueva base de datos plataformas y sus bases de datos pueden
ser fácilmente portadas sin ninguna confi-
$ sqlite3 prueba.db guración o administración
SQLite version 3.3.10 • Estabilidad: SQLite es compatible con
Enter ".help" for instructions ACID, reunión de los cuatro criterios de
sqlite> CREATE TABLE personal ( Atomicidad, Consistencia, Aislamiento y
...> id smallint primary key, Durabilidad
...> nombre varchar(25), • SQL: SQLite implementa un gran sub-
...> apellido varchar(25), conjunto de la ANSI - 92 SQL estándar,
...> direccion varchar(25) incluyendo sub-consultas, generación de
...> ); usuarios, vistas y triggers
sqlite> • Interfaces: SQLite cuenta con diferentes
interfaces del API, las cuales permiten
Estructura Sql : trabajar con C++, PHP, Perl, Python, Tcl,
CREATE TABLE nombre (campo1 tipo, campo2 tipo, campo3 tipo,.., campoN groovy, etc.
tipo); • Costo: SQLite es de dominio público, y
por tanto, es libre de utilizar para cualquier
Listado 2.XXXXXXXXXXXXXXXXXXXX propósito sin costo y se puede redistribuir
libremente.
sqlite> .help
.databases List names and files of attached databases Características de SQLite
.dump ?TABLE? ... Dump the database in an SQL text format SQLite goza de un par de características que
.echo ON|OFF Turn command echo on or off lo hacen único, alguna de ellas se detallan a
.exit Exit this program continuación.
.explain ON|OFF Turn output mode suitable for EXPLAIN on or off.
.header(s) ON|OFF Turn display of headers on or off Cero Configuración
.help Show this message De la forma en que fue concebido y diseñado
.import FILE TABLE Import data from FILE into TABLE SQLite, NO necesita ser instalado. No prender,
.indices TABLE Show names of all indices on TABLE reiniciar o apagar un servidor, e incluso confi-
.mode MODE ?TABLE? Set output mode where MODE is one of: gurarlo. Esta cualidad permite que no haya un
csv Comma-separated values administrador de base de datos para crear las
column Left-aligned columns. (See .width) tablas, vistas, asignar permisos. O bien la adop-
html HTML <table> code ción de medidas de recuperación de servidor
insert SQL insert statements for TABLE por cada caída del sistema.
line One value per line
list Values delimited by .separator string Portabilidad
tabs Tab-separated values SQLite puede ser ejecutado en diferentes
tcl TCL list elements sistemas operativos, como ser Windows, Li-
.nullvalue STRING Print STRING in place of NULL values nux, BSD, Mac OS X, Solaris, HPUX,AIX o
.output FILENAME Send output to FILENAME estar embebido en muchos otros como QNX,
.output stdout Send output to the screen VxWorks, Symbian, Palm OS, Windows CE.
.prompt MAIN CONTINUE Replace the standard prompts Se pude notar que muchos de ellos trabajan a
.quit Exit this program 16, 32 y 64 Bits. La portabilidad no está dada
.read FILENAME Execute SQL in FILENAME en sí por el software, sino por la base de datos
.schema ?TABLE? Show the CREATE statements condensada en un solo archivo, que puede estar
.separator STRING Change separator used by output mode and .import situado en cualquier directorio, trayendo como
.show Show the current values for various settings ventaja que la base de datos puede ser fácil-
.tables ?PATTERN? List names of tables matching a LIKE pattern mente copiada a algún dispositivo USB o ser
.timeout MS Try opening locked tables for MS milliseconds enviada vía correo electrónico.
.width NUM NUM ... Set column widths for "column" mode En cambio, los motores de base de datos
sqlite> 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 disco necesario para almacenar la información utilizados. Pero estos motores se siguen rigien-
datos sean más seguros y más difíciles de acce- real del campo. Tomando el ejemplo anterior, si do por la ley de derechos de autor. SQLite es
der. Algunos proporcionan la opción de escribir quisiera almacenar un solo carácter en un cam- diferente ya que en el derecho de autor la ley
directamente en el disco y pasar por el sistema po definido como VARCHAR(100), entonces simplemente no se aplica, todos pueden contri-
de ficheros todos juntos. Esto aporta un mayor un único byte de espacio de disco se consume. buir, modificar, estudiar y compartir libremente
rendimiento, pero a costa de una considerable Realmente una característica especial para aho- SQLite.
complejidad de instalación y mantenimiento. rrar espacio en memoria.
El uso de registros de longitud variable Limitaciones
Registros de longitud variable por SQLite, tiene una serie de ventajas, entre Una vez escuché decir que no existía un soft-
Generalmente los motores asignan una canti- ellas el resultado de un pequeño archivo de ware al cual no se le encontraran limitaciones.
dad fija de espacio en disco para cada fila en base de datos y optimización de la velocidad de SQLite no está exento de esto, algunas de las
la mayoría de los campos de una determinada la misma, puesto que hay menos información limitaciones son las siguientes:
tabla. Por ejemplo, tomemos un campo de desperdiciada que leer y recorrer.
tipo VARCHAR(100), esto significa que el • Limitaciones en Where: esta limitación
motor le asignará 100 bytes de espacio fijo en Pedagógico está dada por el soporte para clausuras
disco, independientemente de la cantidad de Algunas veces cuando se está en un ámbito edu- anidadas.
información que se almacene en ese campo. cativo, se tiende a enseñar SQL para administrar • Falta de Clave Foránea: se hace caso omi-
En cambio, SQLite realizará todo lo contrario, las bases de datos. Muchas veces transportar so de las claves foráneas; esto quiere decir,
utilizando para ello la cantidad de espacio en una base a casa no es tarea fácil, por eso SQLite cuando se realice la creación de la tabla
está siendo adoptado de una forma pedagógica. desde el modo consola, está permitiendo el
Listado 3.XXXXXXXXXXXXXXXXXXXXX Por ejemplo, los estudiantes pueden enviar vía uso de la clausura, aunque no realizara el
e-mail las bases de datos a los docentes para su chequeo de la misma.
sqlite> .mode list presentación y los docentes realizarán las obser- • Falta de documentación en español: al
sqlite> SELECT * FROM personal; vaciones necesarias. Para los estudiantes más momento de escribir este artículo es muy
1|Juan|Perez|YYYXXXZZZ avanzados que están interesados en el estudio de escasa la documentación disponible en
2|Ramon|Gomez|ZZZXXXYYY cómo trabaja un RDBMS, el código SQLite pue- español sobre SQLite.
sqlite> de servir como una buena base. Esto no quiere
decir que es un modelo exacto de la forma en que Introducción al uso de SQLite
Listado 4.XXXXXXXXXXXXXXXXXXXXX los motores de bases de datos se apliquen, sino SQLite, al igual que muchos de los motores de
una forma en la que un estudiante que entiende bases de datos, posee su administración prede-
sqlite> .separator ", " cómo funciona SQLite puede comprender los finida a través del uso de la consola o terminal,
sqlite> SELECT * FROM personal; principios operativos de otros sistemas. aquellas personas que pudieron administrar an-
1, Juan, Perez, YYYXXXZZZ tes otros motores como por ejemplo es el caso
2, Ramon, Gomez, ZZZXXXYYY La arquitectura SQLite de MySQL, sabrán que no es el único admi-
sqlite> Cada motor de base de datos compila cada nistrador que se conoce sino más bien existen
sentencia SQL en algún tipo de estructura de una amplia gama para la elección, por ejemplo
Listado 5.XXXXXXXXXXXXXXXXXXXXX datos interna que luego se utilizará para llevar phpMyAdmin. Con SQLite sucede lo mismo:
a cabo la labor de la declaración. En SQLite, es posible administrarlo desde varios sistemas,
sqlite> .mode line compilar la forma de las declaraciones es un como es el caso de phpSQLiteAdmin, Visual
sqlite> SELECT * FROM personal; breve programa en un lenguaje de máquina co- SQLite, realSqlserver.
id = 1 mo representación. Los usuarios podemos ver
nombre = Juan la máquina virtual antes poniendo EXPLAIN
apellido = Perez como palabra clave para una consulta. El uso
direccion = YYYXXXZZZ de la VM dentro de SQLite ha sido un gran
beneficio para el desarrollo de la biblioteca, ya
id = 2 que proporciona un cruce entre la interfaz de
nombre = Ramon usuario que analiza las sentencias SQL y la par-
apellido = Gomez te en la cual la máquina virtual ejecuta el código
direccion = ZZZXXXYYY para calcular el resultado, así también utilizar la
sqlite> capacidad de rastreo de la ejecución de la VM
en cada sentencia e imprimir las mismas.
Listado 6.XXXXXXXXXXXXXXX
Licencia de Dominio Público
sqlite> .mode column SQLite se encuentra bajo esta licencia, por ende
sqlite> SELECT * FROM personal; ninguna reivindicación se hace de los derechos
1 Juan Perez YYYXXXZZZ de autor en cualquier parte del núcleo del có-
2 Ramon Gomez ZZZXXXYYY digo fuente. Existen otros motores de bases de
sqlite> 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 sqlite>
Su instalación se pude realizar por medio de (Listado 1). Como habrán podido observar en el Estructura en SQL:
los repositorios o a través de su fuente, como ejemplo, una vez creado el archivo prueba.db SELECT Campo1, Campo2,..,
observaremos a continuación. (de ahora en adelante nuestra base de datos) y Campo4 FROM Tabla ;
con la ayuda del lenguaje SQL, hemos creado
A través de los repositorios una tabla llamada personal con cuatro campos La consulta realizada anteriormente lista todos
Como ya es costumbre, si tenemos nuestra (id, nombre, apellido, dirección). Podemos ob- los campos y todos los registros de la tabla
distribución predilecta y contamos con acceso servar que la forma de escritura es más cómoda, personal, pero es posible listar únicamente los
a Internet o tenemos los DVD de repositorios puesto que podemos escribir de manera prolija campos que deseamos que aparezcan en la con-
y contamos con los permisos de super usuario el armado de una tabla, con los delimitadores en sulta. Para ello los separamos por medio del “,”
root, tipeamos lo siguiente: sentencia “,” y el fin de la misma a través del y además podemos agregarle la cláusula WHERE
limitador”;”. Ahora realizaremos la inserción de para poder filtrar registros que cumplan con una
aptitude install sqlite3 algunos datos para el ejemplo que hemos creado determinada condición, por ejemplo:
de la siguiente manera:
Si contamos con los códigos fuentes descar- sqlite> SELECT id, nombre,
gados desde el sitio oficial de SQLite http: sqlite> INSERT INTO personal apellido FROM personal
//www.sqlite.org/download.html, simplemente VALUES(1, 'Juan', 'Perez', WHERE id <= 2;
deberemos realizar los siguientes pasos: 'YYYXXXZZZ'); 1|Juan|Perez
sqlite> INSERT INTO personal 2|Ramon|Gomez
• Descomprimimos los fuentes de SQLi- VALUES(2, 'Ramon', 'Gomez', sqlite>
te en alguna carpeta con tar xzf 'ZZZXXXYYY');
sqlite.tar.gz Una vez vistas estas operaciones básicas como
• Ejecutamos el script ./configure Estructura en SQL: son la creación de una base de datos, la creación
• Ejecutamos make install para realizar la de una tabla, agregación de datos a la tabla y
instalación en el sistema INSERT INTO TABLA realización de consultas, es posible que quera-
VALUES(val1,val2,val3,.., valn); mos salir del editor o administrador de SQLite
Si deseamos instalar SQLite en el sistema ope- para lo cual tipeamos lo siguiente:
rativo Windows, la instalación se realizará de la Nuevamente observemos la inserción de los da-
siguiente forma: descargamos los ejecutables de tos con la sentencia INSERT de SQL, haciendo sqlite> .quit
SQLite, usamos la consola de línea de coman- referencia a la tabla y posteriormente los valo-
dos de Windows cmd, nos posicionamos en la res para el nuevo registro. Ahora bien, aprendamos algunos comandos
carpeta y ejecutamos el archivo sqlite3.exe, Seguramente en algún momento vamos a especiales para movernos sobre SQLite en
el cual disparará la consola de sqlite3. contar con la necesidad de realizar consultas modo texto, ya que de esta manera nos vamos
sobre las tablas creadas. Para este fin podemos a poder mover con mayor facilidad, seguridad
Primeros pasos con SQLite realizarlo de la siguiente manera: y rapidez. La mayoría de las veces SQLite lee
Una vez que hemos instalado SQLite en nuestro las líneas de entrada y las transforma a las de
sistema, nos posicionaremos en algún directorio sqlite> SELECT * la librería SQLite para luego ejecutarlas. Si
vacío y realizaremos la creación de una nueva FROM personal; una línea de entrada empieza con un punto
base de datos. Recordemos que él, a diferencia 1|Juan|Perez|YYYXXXZZZ ("."), es interpretado inmediatamente por el
de los otros motores de bases de datos, se en- 2|Ramon|Gomez|ZZZXXXYYY 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 coman-
dos 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
Figura 2. Creación de la Base de Datos en consola modo, para lograr estas diferentes salidas. La
modalidad por defecto es en la cual SQLite
nos muestra los datos tras una consulta rea-
lizada previamente. Esta consulta estándar es
separada por este símbolo: "|". Para acceder a
la base de datos creada anteriormente, tipea-
Figura 3. Inserción en tablas desde consola mos lo siguiente: $ sqlite3 prueba.db

www.lpmagazine.org 5
programación
SQLite

Una vez dentro de la misma, podemos realizar el nombre de la tabla en la cual se incluirán estos caso omiso de la misma dentro de su estructura.
lo que presenta el listado 3. Ahora bien si utilizas INSERT. Lo vemos mas claro en el ejemplo A pesar de ser considerado una librería, SQLite
.separator va a cambiar el modo de separación mostrado en el Listado 8. ha abierto un nuevo ENTORNO Y ENFOQUE
de la consulta, por ejemplo lo vamos a hacer Para finalizar tenemos el modo html. En al tratamiento de base de datos, pasó de ser una
cambiar por una coma y un espacio "," (Listado este modo SQLite3 escribe los resultados de la simple librería a un esquema mucho más amplio.
4). En el modo line o línea, cada columna de un consulta en una tabla XHTML, utilizando las fa- Desde SQLite Latinoamérica, hemos llamado al
registro de la base de datos se muestra en una lí- mosas y conocidas etiquetas HTML (Listado 9). mismo esquema como PseudoMotor, algo que
nea por sí mismo. Cada línea está formada por el Por defecto SQLite3 envía los resultados de una aparenta ser un motor pero no lo es. Esto se
nombre de la columna, el signo igual "=" y el da- determinada consulta a la salida estándar que es debe a que contiene dentro de sí mismo muchas
to correspondiente. Ahora el separar los registros seguramente la terminal o Konsole que utilizas características de los grandes motores de base de
se realiza por una línea en blanco (Listado 5). para realizar estas pruebas. Es posible cambiar datos, como ser: la creación de usuarios, vistas,
En el modo column o columna, cada regis- estas salidas usando el comando .output. Sim- triger, etc. Otra cualidad interesante que hemos
tro se muestra con una línea separada con los plemente hay que colocar el archivo de salida co- expuesto desde la comunidad es la capacidad de
datos alineados en las columnas, miremos el mo argumento de .output y todos los resultados poder definir la integridad referencial a través de
ejemplo presentado en el listado 6. Vemos que de esa consulta serán escritos en ese archivo de los trigger, haciéndolo casi similar a un motor de
por defecto cada columna posee un ancho de 10 salida. Si queremos que vuelva a la salida están- base de datos, pero manteniendo la sencillez y
caracteres, donde los datos que quizás sean de- dar: .output stdout . Mira el Listado 10. simplicidad de una librería.
masiado grandes se pueden truncar o recortar. El programa SQLite3 viene con varios co-
Afortunadamente para ello podemos ajustar el mandos que son útiles para analizar el esquema SQLite y los lenguajes de pro-
ancho de la columna con .width como en el de la base de datos. No hay nada que hagan gramación
siguiente ejemplo: estos comandos que no pueda hacerse por otros En los siguientes párrafos mostraremos a través
medios. Estos comandos facilitan únicamente de algunos ejemplos cómo implementar SQLite
sqlite> .width 12 6 un atajo. Por ejemplo, para ver las tablas de para algunos de los lenguajes existentes y algu-
nuestra base de datos .tables: nas cualidades de los mismos.
en donde los valores que se coloquen allí son
totalmente correspondientes a la columna de sqlite> .tables Sqlite y Java
la consulta que se va a realizar. El 12 significa personal Java implementa la conexión a la fuente de
que el espacio será de 12 caracteres, 6 es para sqlite> datos a través de las librerías JDBC. Desde
la columna de apellido y así podemos continuar hace algún tiempo se encuentran disponibles
con los demás. Las etiquetas o nombre de cada En SQLite podemos realizar copias de seguri- las SQLiteJDBC, en Zentus (www.zentus.com/
columna que aparecen de manera de referencia dad de las tablas de nuestra base de datos, para sqlitejdbc/). De allí podremos descargar los
pueden activarse y desactivarse mediante .hea- ello vamos a ver un ejemplo. Simplemente hay JDBC de SQLite para plataformas Linux,
der con los valores ON y OFF. Si tomamos el que colocar el nombre del archivo con el argu- Mac OS, y Windows. Para poder trabajar con
ejemplo anterior podemos verlo mejor en el mento .output, luego el modo, en este caso SQLite y Java debemos realizar una simple co-
Listado 7. El modo de salida, que quizás sea .mode insert personal: para ver las senten- nexión. La realizaremos por medio de una clase
muy útil, es el modo insert o insertar. En este cias de inserciones. .schema personal es el la cual llamaremos coneccion. Debe contar con
modo la salida se formatea para que parezca esquema de la tabla. Así al finalizar tenemos la estructura mostrada en el Listado 12.
un INSERT de SQL. Al especificar este nuevo una copia de seguridad de las tablas de la base
modo, tienes que dar un argumento extra que es de datos (Listado 11). El detalle de los métodos
El nombre de conector que se utilizará nos in-
Listado 7.XXXXXXXXXXXXXXXXXXXX SQLite: 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 .
sqlite> .header on este punto. Muchos de los usuarios de software Aquí se indica el driver con que trabajare-
sqlite> SELECT * FROM personal; libre y desarrolladores, al ver el funcionamiento mos jdbc: sqlite y el nombre de la base de
id nombre apellido direccion 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.
1 Juan Perez YYYXXXZZZ simples: la integridad referencial es el control de getConnection("jdbc:sqlite:" +
2 Ramon Gomez ZZZXXXYYY la clave foránea. Si bien en SQLite, cuando se nombreDB);
sqlite> crea una tabla, se pude invocar a la palabra re-
servada forean key. Pero el compilador realizará El flujo para realizar las sentencias abre el si-
guiente comando:

varSentencia = this.varConeccion.
createStatement();

Hasta este punto sólo hemos realizado la co-


nexión de la base de datos a través de la clase
Figura 4. Envío de una consulta 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 te en PHP empiezan por sqlite_ y son similares
que es executeUpDate el cual permite enviar las recuperación de datos con Java y SQLite. a los que permiten acceder a otras bases de datos
consultas al motor. Su estructura es la siguiente: Se recorre todo el resulset y cada elemen- utilizables desde PHP (MySQL, PostgreSQL,
to-producto de las consultas, se deposita en la etc). El manual de PHP incluye un capítulo dedi-
sentancia.executeUpdate instancia persona que es un objeto de la clase cado a SQLite, es por ello que nos va a permitir
(Sentencia SQL) vector. Luego podremos listar todo el conte- programar mas rápidamente y acostumbrarnos a
nido del vector simplemente recorriéndolo y la sintaxis de una forma casi inmediata.
Si se desea crear una tabla se debería de llamar mostrando su contenido.
a ese método con la consulta de la siguiente Creación/Acceso a la base de datos
manera: SQLite y PHP En SQLite, una base de datos es normalmente
En la versión 4 de PHP, SQLite se podía utilizar un fichero, aunque también pueden abrirse ba-
sentancia.executeUpdate(“CREATE como base de datos instalando un módulo PE- ses de datos en memoria. Este concepto ya lo
TABLE personal (id smallint CL. A partir de la versión 5 de PHP, SQLite está vimos al principio. Por esta razón necesitamos
primary key, nombre incluido en PHP, por lo que está disponible sin un mecanismo para poder abrir la base de datos,
varchar(25))”); necesidad de realizar ninguna instalación adicio- la función es sqlite_open(). El argumento de
nal, realmente una ventaja a la hora de progra- sqlite_open() es la ruta del archivo en el ser-
Ahora si se quiere recuperar datos de la tabla re- mar y se puede observar la gran aceptación de vidor (o :memory: en el caso de crear la base de
cién creada es necesario escribir un método que este pseudo motor. Los nombres de las funciones datos en memoria). En caso de que la base de
recupere objetos y objetos de la clase personal. de PHP que permiten utilizar y manipular SQLi- datos no exista, la función se encarga de crear
una base de datos nueva. La función devuelve
Listado 8.XXXXXXXXXXXXXX un manejador (handle), que se utiliza en el resto
de funciones que acceden a la base de datos.
sqlite> .mode insert nueva_tabla En el siguiente ejemplo, la variable $rutadb
sqlite> SELECT * FROM personal; almacena la ruta o path de donde se encuentra
INSERT INTO nueva_tabla VALUES(1,'Juan','Perez','YYYXXXZZZ'); la base de datos y la variable $db el manejador
INSERT INTO nueva_tabla VALUES(2,'Ramon','Gomez','ZZZXXXYYY'); de la base de datos:
sqlite>
<?php
Listado 9.XXXXXXXXXXXXXXXXXX $rutadb = "prueba.db";
$db = sqlite_open($rutadb) or
<TABLE></TABLE>, <TR>, <TH> y <TD> die("No es posible abir la
base de datos ");
sqlite> .mode html ?>
sqlite> SELECT * FROM personal;
<TR><TH>id</TH><TH>nombre</TH><TH>apellido</TH><TH>direccion</TH></TR> Consultas a la base de datos
<TR><TD>1</TD> Una vez abierta la base de datos, se pueden
<TD>Juan</TD> realizar consultas del lenguaje SQL utilizando
<TD>Perez</TD> varias funciones. Cada función devuelve el re-
<TD>YYYXXXZZZ</TD> sultado de la consulta de forma distinta:
</TR>
<TR><TD>2</TD> • sqlite_array_query(handle, consulta,
<TD>Ramon</TD> tipo): devuelve la consulta en forma de
<TD>Gomez</TD> matriz
<TD>ZZZXXXYYY</TD> • sqlite_exec(consulta): devuelve simple-
</TR> mente verdadero o falso, pero no los datos
sqlite> • sqlite_query(handle, consulta): devuel-
ve un manejador del resultado
Listado 10.XXXXXXXXXXXXXXXXXXXX • sqlite_single_query(handle, consulta,
primera_línea): devuelve únicamente una
sqlite> .mode list columna o la primera fila del resultado
sqlite> .separator | • sqlite_unbuffered_query(handle, con-
sqlite> .output archivo_salida_1.txt sulta): devuelve la consulta sin prefecht
sqlite> SELECT * FROM personal;
sqlite> .exi La función sqlite_array_query() devuelve
$ cat archivo_salida_1.txt la respuesta de la consulta en forma de matriz.
1|Danyx|Maldoando|YYYXXXZZZ No es conveniente utilizar esta función si el
2|LaRepa|Web|ZZZXXXYYY resultado de la consulta contiene muchos re-
$ gistros, ya que puede ocupar mucha memoria
en el servidor.

www.lpmagazine.org 7
programación
SQLite

Varias consultas <?php apellido = 'López' WHERE id =


En estos ejemplos, la variable $db es un sqlite_query($db, "DROP '4'");
manejador creado con sqlite_open() como TABLE personal"); ?>
vimos anteriormente. Para crear una nueva ?>
tabla, se utiliza la consulta CREATE TABLE. Para borrar un registro de una tabla, se utiliza la
Para crear un campo índice hay que definirlo Para añadir un registro a una tabla específica, se consulta DELETE FROM. Nuevamente debemos
INTEGER PRIMARY KEY, y los demás campos utiliza la consulta INSERT INTO: especificar cuál es el registro que deseamos
se crean colocando el nombre que va a llevar <?php eliminar:
dicho campo y, si quisiéramos, qué tipo de
datos va a contener. Para el ejemplo vamos sqlite_query($db, "INSERT <?php
a crear la tabla personal con los campos id, INTO personal VALUES sqlite_query($db, "DELETE
nombre y apellido: (NULL , 'Marcelo' , 'Perez')" ); FROM personas WHERE
?> id = '1'");
<?php ?>
sqlite_query($db, "CREATE Para modificar un registro de una tabla especí-
TABLE personal (id INTEGER fica, se utiliza la consulta UPDATE. Es necesario Quizás, sí lo habrás notado, las consultas SQL
PRIMARY KEY, nombre, identificar con la cláusula WHERE cuál es el son las mismas que implementamos siempre en
apellido)"); registro que vamos a modificar: nuestras aplicaciones y son totalmente compati-
?> bles y válidas, lo único que varía son las funcio-
<?php nes que llamamos, propias de cada librería.
Ahora bien si lo que deseamos es borrar una sqlite_query($db, "UPDATE
tabla, utilizamos la consulta DROP TABLE: personal SET nombre = 'Juan', 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


Ahora ya estamos listos para poder comenzar a
Figura 5. Vista del .header en consola trabajar con pysqlite, en primer lugar debemos
importar esta librería para poder hacer uso de la
Listado 11.XXXXXXXXXXXXXXXX misma: >>> from pysqlite2 import dbapi2
as sqlite
sqlite> .output backup.sql
sqlite> .mode insert personal Con esto ya podemos hacer uso de las libre-
sqlite> .schema personal rías. Ahora lo que vamos a hacer es crear una
sqlite> SELECT * FROM personal; nueva base de datos para poder trabajar sobre
sqlite> .quit la misma. La conexión con la base de datos
se realiza instanciando un objeto y envian-
Listado 12.XXXXXXXXXXXXXXXXXXXXXXXX do como parámetro el archivo, en caso que
el archivo o la base de datos no exista hay
package pruebaBD; que encargarse de crearla y en caso que esté
import org.sqlite.*; creada sólo abrirla: >>> conexion = sqlite
import java.sql.Connection; .connect('prueba.db')
import java.sql.Statement;
Una vez que tengamos la conexión realiza-
public class Coneccion { da, debemos crear un objeto cursor, ésto se
private Connection varConeccion; realiza llamando al método cursor de nuestro
private Statement varSentencia; objeto: >>> cursor = conexion.cursor()

public Coneccion(){ Escribiendo datos con Python


Class.forName("org.sqlite.JDBC"); Una vez realizada la conexión, ya estamos
varConeccion = DriverManager.getConnection("jdbc:sqlite:" + “base.sql”); dispuestos a crear y guardar datos en nuestra
varSentencia = varConeccion.createStatement(); 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:

8 Linux+ 9/2007
programación
SQLite

>>> cursor.execute('CREATE VARCHAR(50), nombre Ahora que ya tenemos creada nuestra tabla,
TABLE personal (id INTEGER VARCHAR(50), email podemos comenzar a cargarle información,
PRIMARY KEY, apellido VARCHAR(100))') 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")')

Figura 6. Salida del formato Html desde consola Estos ejemplos son a modo de visualizar el
modo en el cual se pueden almacenar datos
Listado 13.XXXXXXXXXXXXXXXXXX en nuestra base de datos. La librería pysqlite
nos permite almacenar datos de otra manera
public personal traertodos() utilizando variables que por ejemplo hemos
{ recuperado de algún Form o Widget:
Vector persona = new Vector();
Resulset rs; >>> apellido = "Gomes"
rs = this.sentencia.executeQuery("SELECT * FROM personal"); >>> nombre = "Carlos"
while (rs.next()) { >>> email = "gcarlos@yahoo.com"
persona.add(personal(rs.getInt("id"), rs.getString("Nombre"))); >>> cursor.execute('INSERT
} INTO personal VALUES
rs.close(); (null, ?, ?, ?)', (apellido,
return personal; nombre, email))
}
} Una vez que terminamos de hacer los cambios,
debemos almacenar estos datos de manera per-
Listado 14.XXXXXXXXXXXXXXXXXXXXXXX manente invocando al método commit de nues-
tro objeto conexion: >>> conexion.commit()
>>> cursor.execute('SELECT * FROM personal') Si intentas cerrar una conexión que ha
>>> for fila in cursor: sido modificada sin invocar al método commit,
print 'ID: ', fila[0] pysqlite plantea un error. Este comportamien-
print 'Apellido: ', fila[1] to puede causar problemas, sin embargo si
print 'Nombre: ', fila[2] ustedes no desean guardar los cambios que
print 'Email: ', fila[3] se han efectuado pueden convocar al método
print '-'*10 rollback de nuestro objeto conexion: >>>
conexion.rollback()
ID: 1
Apellido: Ramos Recuperando datos con Python
Nombre: Juan Ahora que tenemos datos almacenados en
Email: juan_85@gmail.com nuestra base de datos, podemos recuperarlos
---------- nuevamente invocando el método execute
de nuestro objeto cursor y haciendo uso del
ID: 2 comando SELECT. Vamos a obtener todos los
Apellido: Juarez valores de la tabla:
Nombre: Martin
Email: martin58j@gmail.com >>> cursor.execute('SELECT
---------- * FROM personal')

ID: 3 El cursor ahora tiene todos los datos de la ta-


Apellido: Gomes bla personal. Existen varias maneras de recu-
Nombre: Carlos perar esos datos. La primera es utilizando el
Email: gcarlos@yahoo.com método fetchall(), el cual nos imprime una
---------- lista con todos los elementos de la siguiente
manera:

www.lpmagazine.org 9
programación
SQLite

>>> cursor.execute >>> cursor.techone() mentación. En este artículo hemos visto unas
('SELECT * FROM (1, "Ramos", "Juan", "juan_ opciones de SQLite que tiene la potencia
personal') 85@gmail.com") de un motor, condensado en una librería o
>>> print cursor.fetchall() Contamos también con el método PseudoMotor.
[(1, "Ramos", "Juan", next(), similar al fetchone() en el sentido Se pueden observar algunas claras
"juan_85@gmail.com"), en que devuelven una única fila. Sin embar- ventajas, como lo es la presencia de las
(2, "Juarez", "Martin", go con este método hay que tener cuidado extensiones, para casi todos los lenguajes
"martin58j@gmail.com"), ya que debemos tener un control del reco- que existen. Cuando Daniel y yo pusimos a
(3, "Gomes", "Carlos", rrido de los datos. Si es que sobrepasamos prueba SQLite, lo realizamos frente a los co-
"gcarlos@yahoo.com")] el límite es posible que nos devuelva un losos del software libre MySQL y PostgreS-
error (Listado 15). Nuevamente podemos QL. Notamos que SQLite es muy rápido en
Creo que es un método muy simple para ver ver la excelente integración de SQLite con respuesta cuando se realizan las consultas y
el contenido por medio de tuplas, pero quizás Python, un lenguaje interpretado y orientado el manejo de los datos. Esto se debe a que no
los datos no tengan un formato adecuado. totalmente a objetos. existe un proceso intermedio para la comu-
Para ello existe una forma también muy Pysqlite, la biblioteca integradora que nicación con el motor. Cosa que sí realizan
sencilla a través del uso de los iteradores permite armar una interfaz muy simple para los ya mencionados motores.
(Listado 14). hacer uso de la misma. Utilizando este tipo Algunos puntos fuertes fueron la caren-
También podemos hacer uso del método de motor de base de datos, como es SQLite, cia de configuraciones y el tener una base
fetchone(), el cual sólo obtiene una fila del podemos lograr aplicaciones móviles de ma- de datos en un solo archivo. No obstante,
cursor, pero no en forma de lista sino como nera muy segura y confiable. hay que aclarar que SQLite tiene algunos
una tupla. Es útil para cuando nosotros sólo puntos flacos como ser que no es apropiado
deseamos ver una única fila o quizás una fila Conclusión para realizar aplicaciones cliente/servidor o
a la vez: Día a día se avanza a pasos agigantados para implementaciones de gran escala, como
en el desarrollo, pero siempre existe ese puede ser un padrón electoral.
>>> cursor.execute desafío que hace al desarrollador definir la Puesto que SQLite se saturaría con las
('SELECT * FROM herramienta que ha de utilizar para realizar peticiones de los usuarios. Por tal motivo
personal') el manejo de los datos dentro de su imple- 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.
Figura 7. Muestra los resultados de aplicar esta forma de backup

Listado 15.XXXXXXXXXXXXXXXXXXXXXX
Sobre los Autores
>>> cursor.execute('SELECT * FROM personal')
Gerardo Antonio Cabero y Daniel Mal-
>>> cursor.next()
donado son argentinos oriundos de las
(1, "Ramos", "Juan", "juan_85@gmail.com")
provincias de Salta y Jujuy. Son admi-
>>> cursor.next()
nistradores y miembros fundadores de
(2, "Juarez", "Martin", "martin58j@gmail.com")
la comunidad de SQLite latinoamérica.
>>> cursor.next()
Ambos se desempeñan como consultores
(3, "Gomes", "Carlos", "gcarlos@yahoo.com")
informáticos en sus respectivas provincias.
>>> cursor.next()
Más información en:
Traceback (most recent call last):
cabero@gmail.com
File "<pyshell#201>", line 1, in -toplevel-
daniregede@hotmail.com
cursor.next()
sqlite-latino.blogspot.com
StopIteration
www.larepaweb.com.ar

10 Linux+ 9/2007