{"id":2042,"library":"geoalchemy2","title":"GeoAlchemy 2","description":"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.","status":"active","version":"0.18.4","language":"en","source_language":"en","source_url":"https://github.com/geoalchemy/geoalchemy2","tags":["SQLAlchemy","GIS","geospatial","PostGIS","database","ORM","spatial","geometry"],"install":[{"cmd":"pip install geoalchemy2","lang":"bash","label":"Install core library"},{"cmd":"pip install geoalchemy2[shapely]","lang":"bash","label":"Install with Shapely support"}],"dependencies":[{"reason":"Required for database interaction and ORM capabilities.","package":"SQLAlchemy","version_constraint":">=1.4"},{"reason":"Optional, but recommended for converting WKB/WKT elements to Shapely geometries and vice-versa (e.g., `to_shape`, `from_shape`).","package":"Shapely","optional":true},{"reason":"Database driver for PostgreSQL/PostGIS (example, other drivers like `mysqlclient` for MySQL or `pyspatialite` for SpatiaLite are also common).","package":"psycopg2-binary","optional":true}],"imports":[{"note":"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.","wrong":"from geoalchemy2.types import Geometry","symbol":"Geometry","correct":"from geoalchemy2 import Geometry"},{"note":"Similar to `Geometry`, `WKTElement` is usually imported from the top-level `geoalchemy2` package.","wrong":"from geoalchemy2.elements import WKTElement","symbol":"WKTElement","correct":"from geoalchemy2 import WKTElement"},{"note":"GeoAlchemy 2 integrates spatial functions directly with SQLAlchemy's `func` object, unlike GeoAlchemy 1 which had its own `functions` namespace.","symbol":"func","correct":"from sqlalchemy import func"},{"note":"Spatial functions like `ST_AsText` are available under `geoalchemy2.functions`.","symbol":"ST_AsText","correct":"from geoalchemy2.functions import ST_AsText"},{"note":"For integration with Shapely, utility functions like `to_shape` and `from_shape` are found in `geoalchemy2.shape`.","symbol":"to_shape","correct":"from geoalchemy2.shape import to_shape"}],"quickstart":{"code":"import os\nfrom sqlalchemy import create_engine, Column, Integer, String\nfrom sqlalchemy.orm import sessionmaker, declarative_base\nfrom sqlalchemy import func\nfrom geoalchemy2 import Geometry, WKTElement\n\n# Ensure you have a PostGIS-enabled database URL set in your environment\n# Example: 'postgresql+psycopg2://user:password@host:port/dbname'\nDATABASE_URL = os.environ.get('GEOALCHEMY_DATABASE_URL', 'postgresql+psycopg2://gis:gis@localhost:5432/gis_test')\n\nBase = declarative_base()\n\nclass City(Base):\n    __tablename__ = 'cities'\n    id = Column(Integer, primary_key=True)\n    name = Column(String)\n    # Define a geometry column for points, SRID 4326 (WGS 84 Lat/Lon)\n    geom = Column(Geometry(geometry_type='POINT', srid=4326))\n\n    def __repr__(self):\n        return f\"<City(name='{self.name}', geom='{self.geom}')>\"\n\n# Create an engine and include the geoalchemy2 plugin\nengine = create_engine(DATABASE_URL, echo=False, plugins=[\"geoalchemy2\"])\n\n# Create all tables in the database\nBase.metadata.create_all(engine)\n\nSession = sessionmaker(bind=engine)\nsession = Session()\n\ntry:\n    # Add a new city with a point geometry using WKTElement\n    new_york = City(\n        name='New York',\n        geom=WKTElement('POINT(-74.0060 40.7128)', srid=4326)\n    )\n    session.add(new_york)\n    session.commit()\n    print(f\"Added: {new_york.name} with geometry {new_york.geom}\")\n\n    # Query the city and retrieve its geometry as WKT\n    retrieved_city = session.query(City).filter_by(name='New York').one()\n    wkt_geom = session.scalar(func.ST_AsText(retrieved_city.geom))\n    print(f\"Retrieved {retrieved_city.name}. Geometry in WKT: {wkt_geom}\")\n\n    # Example of a spatial query: find cities containing a point\n    # (This assumes a larger dataset or more complex geometry for a meaningful result)\n    point_to_check = WKTElement('POINT(-74.0060 40.7128)', srid=4326)\n    cities_containing_point = session.query(City).filter(\n        func.ST_Contains(retrieved_city.geom, point_to_check)\n    ).all()\n    print(f\"Cities containing point {point_to_check.data}: {[c.name for c in cities_containing_point]}\")\n\nexcept Exception as e:\n    session.rollback()\n    print(f\"An error occurred: {e}\")\nfinally:\n    session.close()\n    # Clean up (optional, for idempotent quickstart)\n    Base.metadata.drop_all(engine)","lang":"python","description":"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."},"warnings":[{"fix":"Upgrade Python to 3.10 or newer, or use an older version of GeoAlchemy 2 compatible with your Python version.","message":"GeoAlchemy 2 dropped support for Python versions older than 3.10 starting from version 0.18.0. Ensure your Python environment meets this requirement.","severity":"breaking","affected_versions":">=0.18.0"},{"fix":"Consult the official 'Migrate to GeoAlchemy 2' documentation for a detailed guide on adapting your code.","message":"Migrating 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.","severity":"breaking","affected_versions":"All versions of GeoAlchemy 2 when migrating from GeoAlchemy 1"},{"fix":"Use `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.","message":"When 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`).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Install with `pip install geoalchemy2[shapely]` if Shapely integration is desired. Be aware of potential `Shapely` import issues in versions prior to 0.18.4.","message":"Shapely 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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}