Cómo leer y grabar datos en PostGIS desde GeoPandas

PostGIS es una herramienta que dota de funciones espaciales al sistema de administración de bases de datos PostgreSQL. El tándem PostgreSQL + PostGIS es uno de los más utilizados para almacenar datos espaciales. Por otro lado, Python se ha convertido en un lenguaje muy utilizado en ciencia de datos y tiene algunas librerías específicas para datos espaciales, como GeoPandas. En este artículo veremos cómo podemos leer datos desde una tabla de PostGIS utilizando GeoPandas y el camino inverso, es decir; cómo crear una tabla y dotarla de contenido desde GeoPandas.

¿Qué necesitamos para comenzar?

Logicamente necesitaremos tener una base de datos en PostGIS y GeoPandas.

GeoPandas es una biblioteca de Python que se basa en la popular librería Pandas, que se combina con Shapely para de esa forma trabajar con datos espaciales.

Podemos instalar GeoPandas mediante pip.

Activa tu entorno virtual (se desaconseja utilizar el entorno base) y escribe la sentencia:

pip install geopandas

También necesitaremos las siguientes herramientas:

SQLAlchemy

  • SQLAlchemy, es una biblioteca de Python que nos permite interactuar con bases de datos relacionales. Está pensada para comunicarnos con bases de datos como MySQL, PostgreSQL, SQLite, Oracle y otras. Necesitamos también, GeoAlchemy2 que es una extensión de la biblioteca SQLAlchemy que agrega soporte para tipos de datos geoespaciales y funciones de geodatabase en bases de datos PostgreSQL con la extensión espacial PostGIS. GeoAlchemy2 se utiliza principalmente para trabajar con datos geoespaciales en aplicaciones Python que utilizan SQLAlchemy como ORM (Object-Relational Mapping) y PostgreSQL/PostGIS como el sistema de gestión de bases de datos.
  • psycopg2 es un adaptador de base de datos PostgreSQL para Python. Permite conectarse a una base de datos PostgreSQL utilizando Python.

En resumen se necesita: Geopandas, SQLAlchemy, psycopg2 y geoalchemy2.

Leer datos de una tabla de PostGIS mediante GeoPandas

Partimos de una base de datos llamada world que contiene una tabla llamada countries.

Lo primero que tenemos que hacer es importar las librerías:

import geopandas as gpd
from sqlalchemy import create_engine

La función create_engine se utiliza para establecer una conexión a una base de datos y configurar la forma en que SQLAlchemy interactuará con esa base de datos.

Definimos la url a la tabla que contiene los datos:

db_connection_url = "postgresql://postgres:postgres@localhost:5432/world"

Esta url tiene la estructura: «postgresql//{usuario}:{password}@{host}:{puerto}/{nombre_database}«

Ahora creamos la conexión en función de la url que hemos definido antes y escribimos la sentencia SQL para obtener los datos:

con = create_engine(db_connection_url)  

sql = "SELECT gid, name, geom FROM public.countries"

Por último, creamos el geodataframe con Geopandas y vemos los datos:

df = gpd.GeoDataFrame.from_postgis(sql, con)
df

En un cuaderno de Jupyter este sería el resultado:

Grabar datos en PostGIS utilizando GeoPandas

Vemos ahora la forma en la que podemos cargar datos en una tabla:

from sqlalchemy import create_engine
import geopandas as gpd
 
user = "postgres"
password = "postgres"
host = "localhost"
port = 5432
database = "world"
 
conn = f"postgresql://{user}:{password}@{host}:{port}/{database}"
engine = create_engine(conn)

Hemos importado las librerías y definido los parámetros de la conexión a la base de datos, que como puedes observar son los mismos que utilizamos antes.

A continuación leemos los datos de origen, que en este ejemplo se encuentran en un archivo en formato shapefile. Utilizamos para ello la función read_file de Geopandas:

#Leemos un shapefile utilizando GeoPandas
gdf = gpd.read_file("Puntos_interes/Puntos_interes.shp")

De este modo hemos creado un geodataframe llamado gdf, que contiene los datos contenidos en el shapefile de origen.

Ahora importamos el geodataframe a la base datos:

gdf.to_postgis(name="Puntos_interes", con=engine, schema="public")
 
print("success")

Como se puede observar en el código anterior se crea una tabla llamada Puntos_interes, en el schema «public» y que estará en la base de datos que habíamos indicado al principio y que se llamaba ‘world‘:

Utilizando PgAdmin podemos ver la nueva tabla llamada Puntos_interes que se ha creado en la base de datos world.

La potencia de Python para acceder a bases de datos y realizar todo tipo de análisis espacial es impresionante. Si estás interesado en aprender a trabajar con librerías de Python como GeoPandas, Matplotlib o Cartopy, inscríbete en nuestro curso online de Analisis GeoEspacial con Python.