En el artículo anterior expliqué cómo instalar un servidor Linux con Apache, Python y MySQL. Ahora voy a explicar cómo lograr la misma combinación pero reemplazando MySQL con PostgreSQL, el motor de bases de datos open source más avanzado.
Instalación de PostgreSQL
Partiendo de un servidor Debian/Devuan con Apache y Python instalados, instalar el motor de bases de datos PostgreSQL ejecutando:
# apt-get install postgresql
Al finalizar la instalación, el paquete ha creado al usuario "postgres", con privilegios de administración sobre el motor de bases de datos (equivalente al usuario "root" de MySQL):
root@devuan:~# cat /etc/passwd | grep postgres postgres:x:105:110:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
Tener en cuenta que PostgreSQL admite una amplia variedad de métodos de autenticación de usuarios, incluyendo el método peer, el cual obtiene el ID del usuario a partir del nombre de usuario del cliente a nivel sistema operativo.
Dependiendo de cada distribución GNU/Linux, podría ser necesario crear una instancia de PostgreSQL antes de continuar.
Creación de un usuario y base de datos
El siguiente paso consiste en crear un usuario y base de datos para la aplicación Web. Para ello, cambiar al usuario "postgres" y ejecutar las siguientes consultas:
root@devuan:~# su - postgres postgres@devuan:~$ psql psql (9.4.6) Type "help" for help. postgres=# create user mypywebapp with password '654321'; CREATE ROLE postgres=# create database mypywebapp owner mypywebapp; CREATE DATABASE postgres=# \q postgres@devuan:~$ exit logout root@devuan:~#
Así se crea al usuario "mypywebapp" con contraseña "654321", junto con la base de datos de igual nombre.
Luego permitir al usuario "mypywebapp" el acceso mediante nombre de usuario y contraseña (método password/md5) desde el archivo de configuración de autenticación pg_hba.conf, el cual se encuentra en la ruta /etc/postgresql/9.4/main/pg_hba.conf
.
Debajo de la configuración del usuario "postgres", agregar la línea para que se autentique al usuario "mypywebapp" mediante el método md5:
# Database administrative login by Unix domain socket local all postgres peer # MyPyWebApp local all mypywebapp md5
Recargar la configuración de PostgreSQL para que tomen efecto los cambios:
root@devuan:~# service postgresql reload [ ok ] Reloading PostgreSQL 9.4 database server: main.
Por último, verificar el acceso con el cliente psql
:
root@devuan:~# psql -d mypywebapp -U mypywebapp -W Password for user mypywebapp: psql (9.4.6) Type "help" for help. mypywebapp=> \q root@devuan:~#
Instalación del driver PostgreSQL para conectarse desde Python
Existen varios drivers Python para PostgreSQL, para diferentes plataformas y versiones de Python. El más popular es psycopg, el cual soporta actualmente todas las versiones de Python desde 2.5 hasta 3.4 sobre plataformas Unix y Windows. Pero en mi caso decidí utilizar el driver pg8000, que está desarrollado íntegramente con Python y es liberado con licencia BSD. Además, es el driver utilizado por el framework Web2Py.
Instalar el driver pg8000 desde el gestor de paquetes pip ejecutando:
root@devuan:~# pip install pg8000 Downloading/unpacking pg8000 Downloading pg8000-1.10.5-py2.py3-none-any.whl Downloading/unpacking six>=1.10.0 (from pg8000) Downloading six-1.10.0-py2.py3-none-any.whl Installing collected packages: pg8000, six Found existing installation: six 1.8.0 Not uninstalling six at /usr/lib/python2.7/dist-packages, owned by OS Successfully installed pg8000 six Cleaning up...
En el sitio oficial existe una buena guía con ejemplos de conexión a PostgreSQL desde Python.
Creación de un script Python para verificar el acceso mediante HTTP
En la raíz de la aplicación Web, crear un archivo para verificar el circuito completo (revisar el artículo Linux+Apache+Python+MySQL para ver la configuración de Apache).
# nano /var/www/mypywebapp/index-postgres.py
El siguiente script se conecta al motor de bases de datos PostgreSQL utilizando el usuario "mypywebapp" para consultar la versión del motor (ejecutando la consulta select version();
):
#!/usr/bin/python # coding=utf-8 # Imprimir los headers HTTP print("Content-Type: text/html") print("") # Imprimir el contenido de la página print("<h2>Hola mundo</h2>") print("<p>Prueba de ejecución de script Python en modo CGI.</p>") # Mostrar la versión de Postgres import pg8000 con = pg8000.connect(user='mypywebapp', password='654321', host='localhost') c = con.cursor() c.execute("select version()") v = "".join(c.fetchone()) print("<p>La versión de PostgreSQL es: <b>%s</b></p>" % v.encode("utf-8"))
Guardar los cambios y ajustar los permisos adecuadamente:
root@devuan:/var/www/mypywebapp# chown root:www-data index-postgres.py root@devuan:/var/www/mypywebapp# chmod +x index-postgres.py
Verificar el funcionamiento desde línea de comandos:
root@devuan:/var/www/mypywebapp# ./index-postgres.py Content-Type: text/html <h2>Hola mundo</h2> <p>Prueba de ejecución de script Python en modo CGI.</p> <p>La versión de PostgreSQL es: <b>PostgreSQL 9.4.6 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit</b></p>
Si todo funciona correctamente, verificar desde un navegador:

Referencias
Programming with Python and PostgreSQL (psychopg)