GeoAlchemy 2

0.18.4 · active · verified Thu Apr 09

GeoAlchemy 2 is a Python library that extends SQLAlchemy to facilitate working with spatial databases. It primarily focuses on PostGIS, offering robust support for geometry, geography, and raster types, while also providing support for SpatiaLite, MySQL, MariaDB, and GeoPackage. It seamlessly integrates with both SQLAlchemy's Object Relational Mapper (ORM) and its SQL Expression Language, enabling users to define spatial columns, leverage spatial functions, and perform spatial operations. The library is actively maintained, with its current version being 0.18.4, and exhibits a regular release cadence.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define a SQLAlchemy ORM model with a GeoAlchemy 2 `Geometry` column, add a new record with a point geometry using `WKTElement`, and perform a basic query to retrieve the geometry in Well-Known Text (WKT) format using `func.ST_AsText`. It requires a PostGIS-enabled database and the `GEOALCHEMY_DATABASE_URL` environment variable set for connection.

import os
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy import func
from geoalchemy2 import Geometry, WKTElement

# Ensure you have a PostGIS-enabled database URL set in your environment
# Example: 'postgresql+psycopg2://user:password@host:port/dbname'
DATABASE_URL = os.environ.get('GEOALCHEMY_DATABASE_URL', 'postgresql+psycopg2://gis:gis@localhost:5432/gis_test')

Base = declarative_base()

class City(Base):
    __tablename__ = 'cities'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    # Define a geometry column for points, SRID 4326 (WGS 84 Lat/Lon)
    geom = Column(Geometry(geometry_type='POINT', srid=4326))

    def __repr__(self):
        return f"<City(name='{self.name}', geom='{self.geom}')>"

# Create an engine and include the geoalchemy2 plugin
engine = create_engine(DATABASE_URL, echo=False, plugins=["geoalchemy2"])

# Create all tables in the database
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

try:
    # Add a new city with a point geometry using WKTElement
    new_york = City(
        name='New York',
        geom=WKTElement('POINT(-74.0060 40.7128)', srid=4326)
    )
    session.add(new_york)
    session.commit()
    print(f"Added: {new_york.name} with geometry {new_york.geom}")

    # Query the city and retrieve its geometry as WKT
    retrieved_city = session.query(City).filter_by(name='New York').one()
    wkt_geom = session.scalar(func.ST_AsText(retrieved_city.geom))
    print(f"Retrieved {retrieved_city.name}. Geometry in WKT: {wkt_geom}")

    # Example of a spatial query: find cities containing a point
    # (This assumes a larger dataset or more complex geometry for a meaningful result)
    point_to_check = WKTElement('POINT(-74.0060 40.7128)', srid=4326)
    cities_containing_point = session.query(City).filter(
        func.ST_Contains(retrieved_city.geom, point_to_check)
    ).all()
    print(f"Cities containing point {point_to_check.data}: {[c.name for c in cities_containing_point]}")

except Exception as e:
    session.rollback()
    print(f"An error occurred: {e}")
finally:
    session.close()
    # Clean up (optional, for idempotent quickstart)
    Base.metadata.drop_all(engine)

view raw JSON →