Install & Compatibility
Where this runs
tested against v0.20.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
43MB installed
● package 43MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Geometry
✓ from geoalchemy2 import Geometry
✗ from geoalchemy2.types import Geometry
While `Geometry` is in `geoalchemy2.types`, it's typically imported directly from the top-level `geoalchemy2` package for convenience and consistency with common usage patterns.
WKTElement
✓ from geoalchemy2 import WKTElement
✗ from geoalchemy2.elements import WKTElement
Similar to `Geometry`, `WKTElement` is usually imported from the top-level `geoalchemy2` package.
func
✓ from sqlalchemy import func
GeoAlchemy 2 integrates spatial functions directly with SQLAlchemy's `func` object, unlike GeoAlchemy 1 which had its own `functions` namespace.
ST_AsText
✓ from geoalchemy2.functions import ST_AsText
Spatial functions like `ST_AsText` are available under `geoalchemy2.functions`.
to_shape
✓ from geoalchemy2.shape import to_shape
For integration with Shapely, utility functions like `to_shape` and `from_shape` are found in `geoalchemy2.shape`.
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)
Debug
Known issues
breakingGeoAlchemy 2 dropped support for Python versions older than 3.10 starting from version 0.18.0. Ensure your Python environment meets this requirement.fixUpgrade Python to 3.10 or newer, or use an older version of GeoAlchemy 2 compatible with your Python version.
affects: >=0.18.0
breakingMigrating from GeoAlchemy 1 to GeoAlchemy 2 involves significant API changes. Notably, specific geometry types like `Point` are replaced by `Geometry(geometry_type='POINT')`, and spatial functions are accessed via SQLAlchemy's `func` object instead of a dedicated `geoalchemy.functions` namespace.fixConsult the official 'Migrate to GeoAlchemy 2' documentation for a detailed guide on adapting your code.
affects: All versions of GeoAlchemy 2 when migrating from GeoAlchemy 1
gotchaWhen querying geometry columns, GeoAlchemy 2 returns `WKBElement` objects by default, which are binary representations (EWKB). To get human-readable formats like WKT or GeoJSON directly from the database, use spatial functions like `func.ST_AsText()` or `func.ST_AsGeoJSON()` in your queries. For in-application processing, convert `WKBElement` to Shapely geometries using `geoalchemy2.shape.to_shape()` (requires `Shapely`).fixUse `func.ST_AsText(your_geom_column)` in your queries for WKT output, or `from geoalchemy2.shape import to_shape; shapely_geom = to_shape(wkb_element)` for Shapely integration.
affects: All versions
gotchaShapely is an optional dependency for GeoAlchemy 2. If you plan to use functions like `to_shape` or `from_shape` for integrating with Shapely geometries, you must install it separately using `pip install geoalchemy2[shapely]`. Recent versions (0.18.3, 0.18.4) specifically addressed `Shapely` import fixes.fixInstall with `pip install geoalchemy2[shapely]` if Shapely integration is desired. Be aware of potential `Shapely` import issues in versions prior to 0.18.4.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'geoalchemy2'
The `geoalchemy2` library is not installed in the Python environment being used, or the environment is not activated.
fixEnsure `geoalchemy2` is installed in your active virtual environment by running: `pip install geoalchemy2`
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedFunction) function st_asewkb(point) does not exist
This error typically indicates that the PostGIS extension has not been enabled in your PostgreSQL database, preventing the database from recognizing spatial functions like `ST_AsEWKB` or `ST_GeomFromEWKT`.
fixConnect to your PostgreSQL database (e.g., via `psql`) and enable the PostGIS extension: `CREATE EXTENSION postgis;`
The migration script misses the relevant imports from geoalchemy2
When using Alembic with `geoalchemy2` and `--autogenerate`, Alembic may not automatically add the necessary `from geoalchemy2 import Geometry` (or other spatial types) imports to the generated migration script, leading to `NameError` when applying the migration.
fixManually add `from geoalchemy2 import Geometry` (or the specific spatial type being used, like `Geography`, `Raster`) to your Alembic migration script. You might also need to adjust `render_item` in `env.py` for custom types.
AttributeError: 'Function' object has no attribute 'items'
This error often occurs when trying to directly serialize SQLAlchemy `func` objects or `WKBElement` instances (which represent spatial data) to JSON using libraries like `simplejson` or `json.dumps` without a proper custom encoder.
fixConvert `WKBElement` objects to a serializable format (e.g., WKT or GeoJSON string) before JSON serialization, often using `func.ST_AsGeoJSON()` or `WKBElement.desc` to get WKT. For `simplejson`, disabling `namedtuple_as_object` and `for_json` options or providing a custom `default` handler can help.
Geometry has Z dimension but column does not
You are attempting to insert or create a table with 3D geometry data (e.g., `LINESTRING Z`) into a database column that is defined for 2D geometries only, or vice-versa, causing a dimension mismatch.
fixEnsure that the `dimension` parameter in your `geoalchemy2.types.Geometry` (or `Geography`) definition matches the dimensionality of the data you intend to store. For 3D data, specify `dimension=3` (e.g., `Column(Geometry(geometry_type='POINTZ', dimension=3))`). If the table is already created, you might need to alter the column type or create a new column with the correct dimension.
Upgrade
Version history
0.20.0latest on PyPI · released May 12, 2026
Audit
Dependencies
SQLAlchemyrequiredRequired for database interaction and ORM capabilities.
ShapelyoptionalOptional, but recommended for converting WKB/WKT elements to Shapely geometries and vice-versa (e.g., `to_shape`, `from_shape`).
psycopg2-binaryoptionalDatabase driver for PostgreSQL/PostGIS (example, other drivers like `mysqlclient` for MySQL or `pyspatialite` for SpatiaLite are also common).