CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-geoalchemy2

Using SQLAlchemy with Spatial Databases

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

database-administration.mddocs/

Database Administration

Administrative functions and tools for managing spatial databases, including automatic DDL event handling, spatial index creation, and database-specific initialization procedures.

Capabilities

DDL Event Management

Automatic management of spatial database schema events with support for spatial indexes and metadata.

def setup_ddl_event_listeners():
    """
    Setup DDL event listeners to automatically process spatial columns.
    
    Automatically called when importing geoalchemy2. Registers event handlers for:
    - before_create: Handle spatial indexes before table creation
    - after_create: Restore column lists and create spatial metadata  
    - before_drop: Remove spatial metadata before table drop
    - after_drop: Clean up spatial references after table drop
    - column_reflect: Handle spatial column reflection during introspection
    - after_parent_attach: Automatically add spatial indexes to columns
    """

The DDL event system automatically handles:

  • Spatial Index Creation: Automatically creates spatial indexes for geometry/geography columns
  • Metadata Management: Manages spatial_ref_sys and geometry_columns tables
  • Column Reflection: Properly reflects spatial column types during database introspection
  • Cross-Database Compatibility: Handles dialect-specific spatial schema requirements

Database Engine Configuration

Spatial database engine initialization and configuration management.

class GeoEngine:
    """
    SQLAlchemy plugin for spatial database engine initialization.
    
    Automatically registered as a SQLAlchemy plugin via entry points.
    Provides database-specific spatial initialization when engines are created.
    """

Usage examples:

from sqlalchemy import create_engine
from geoalchemy2.admin.plugin import GeoEngine

# Engine automatically configured for spatial operations
engine = create_engine(
    'postgresql://user:pass@localhost/spatial_db',
    plugins=[GeoEngine()]  # Explicitly add if needed
)

# Or use standard engine creation (plugin auto-registered)
engine = create_engine('postgresql://user:pass@localhost/spatial_db')

SpatiaLite Initialization

Initialize SpatiaLite extension for SQLite databases with spatial capabilities.

def load_spatialite(dbapi_conn, *args):
    """
    Load SpatiaLite extension for SQLite database connections.
    
    Parameters:
    - dbapi_conn: SQLite database connection
    - *args: Additional arguments (unused)
    
    Automatically loads the SpatiaLite extension library and initializes
    spatial metadata tables. Use as a SQLAlchemy engine event listener.
    """

Usage examples:

from sqlalchemy import create_engine, event
from geoalchemy2.admin.dialects.sqlite import load_spatialite

# Method 1: Using engine events
engine = create_engine('sqlite:///spatial.db')
event.listen(engine, 'connect', load_spatialite)

# Method 2: Direct import triggers automatic setup
from geoalchemy2 import load_spatialite
engine = create_engine('sqlite:///spatial.db')
# load_spatialite automatically registered as connect event

# Create tables with spatial columns
Base.metadata.create_all(engine)

GeoPackage Initialization

Initialize GeoPackage databases with OGC standard compliance and spatial capabilities.

def load_spatialite_gpkg(dbapi_conn, *args, **kwargs):
    """
    Load SpatiaLite extension for GeoPackage database connections.
    
    Parameters:
    - dbapi_conn: SQLite database connection for GeoPackage
    - *args: Additional arguments
    - **kwargs: Keyword arguments including connection parameters
    
    Initializes GeoPackage-specific spatial capabilities including:
    - OGC GeoPackage standard compliance
    - Spatial reference system metadata
    - Built-in R-tree spatial indexing
    """

Usage examples:

from sqlalchemy import create_engine, event  
from geoalchemy2.admin.dialects.geopackage import load_spatialite_gpkg

# Initialize GeoPackage database
engine = create_engine('sqlite+pysqlite:///data.gpkg')
event.listen(engine, 'connect', load_spatialite_gpkg)

# Create spatial tables following GeoPackage standard
Base.metadata.create_all(engine)

Dialect Selection

Select appropriate database dialect implementations for spatial operations.

def select_dialect(dialect_name: str):
    """
    Select database dialect implementation for spatial operations.
    
    Parameters:
    - dialect_name: str, database dialect name
        ("postgresql", "mysql", "mariadb", "sqlite", "geopackage")
    
    Returns:
    Dialect-specific implementation module with functions:
    - before_create, after_create, before_drop, after_drop
    - reflect_geometry_column
    - bind_processor_process
    """

Supported dialects:

  • postgresql: PostGIS-specific implementations
  • mysql: MySQL spatial extension support
  • mariadb: MariaDB spatial optimizations
  • sqlite: SpatiaLite extension integration
  • geopackage: OGC GeoPackage standard support

Spatial Index Management

Automatic and manual spatial index creation and management.

# Automatic index creation via column attachment events
def after_parent_attach(column, table):
    """
    Automatically add spatial indexes when spatial columns are attached to tables.
    
    Creates appropriate spatial indexes based on:
    - Column type (Geometry, Geography, Raster)
    - Database dialect capabilities
    - Index configuration options (N-D indexes, etc.)
    """

Manual index management:

from sqlalchemy import Index
from geoalchemy2.admin.dialects.common import _spatial_idx_name

# Create spatial index manually
spatial_index = Index(
    _spatial_idx_name('table_name', 'geom_column'),
    MyTable.geom,
    postgresql_using='gist'
)

# For N-D indexes (PostgreSQL)
nd_index = Index(
    _spatial_idx_name('table_name', 'geom_column') + '_nd',
    MyTable.geom,
    postgresql_using='gist',
    postgresql_ops={'geom': 'gist_geometry_ops_nd'}
)

Database-Specific Administration

PostgreSQL/PostGIS Administration

# PostGIS-specific initialization
from geoalchemy2.admin.dialects import postgresql

# Automatic handling of:
# - PostGIS extension loading
# - spatial_ref_sys table management  
# - geometry_columns metadata
# - Advanced indexing options (GiST, SP-GiST, BRIN)

MySQL/MariaDB Administration

# MySQL spatial administration
from geoalchemy2.admin.dialects import mysql, mariadb

# Handles:
# - Geometry type validation
# - SRID constraint enforcement
# - Spatial index creation with R-tree
# - NOT NULL constraints for indexed columns

SQLite/SpatiaLite Administration

# SpatiaLite administration
from geoalchemy2.admin.dialects import sqlite

# Manages:
# - SpatiaLite extension loading
# - Spatial metadata initialization
# - Virtual spatial index tables
# - Geometry column registration

GeoPackage Administration

# GeoPackage administration  
from geoalchemy2.admin.dialects import geopackage

# Provides:
# - OGC GeoPackage standard compliance
# - Built-in spatial reference systems
# - R-tree spatial indexing
# - Geometry type enforcement

Administrative Workflows

New Spatial Database Setup

Complete setup workflow for new spatial databases:

from sqlalchemy import create_engine, MetaData
from geoalchemy2 import Geometry, load_spatialite
from geoalchemy2.admin import setup_ddl_event_listeners

# 1. Create engine with appropriate dialect
engine = create_engine('postgresql://user:pass@localhost/new_spatial_db')
# or for SQLite
engine = create_engine('sqlite:///new_spatial.db')

# 2. DDL events automatically set up via import
# setup_ddl_event_listeners() called automatically

# 3. Define spatial models
class SpatialTable(Base):
    __tablename__ = 'spatial_features'
    
    id = Column(Integer, primary_key=True)
    name = Column(String)
    geom = Column(Geometry('POLYGON', srid=4326))  # Index auto-created

# 4. Create all tables and indexes
Base.metadata.create_all(engine)

Database Migration Support

Support for evolving spatial schemas:

# Spatial columns automatically handled during reflection
from sqlalchemy import MetaData

metadata = MetaData(bind=engine)
metadata.reflect()

# Spatial columns properly reflected with types and indexes
spatial_table = metadata.tables['spatial_features']
geom_column = spatial_table.c.geom  # Properly typed as Geometry

# Existing spatial indexes automatically discovered
spatial_indexes = [idx for idx in spatial_table.indexes 
                  if 'gist' in str(idx) or 'spatial' in idx.name]

Cross-Database Compatibility

Ensure spatial operations work across different database backends:

from geoalchemy2.admin import select_dialect

# Automatically handles dialect differences
def create_spatial_table(engine):
    dialect = select_dialect(engine.dialect.name)
    
    # Dialect-specific setup handled automatically
    Base.metadata.create_all(engine)
    
    # Spatial indexes created appropriately for each database
    return True

# Works with any supported database
postgres_engine = create_engine('postgresql://...')
sqlite_engine = create_engine('sqlite://...')
mysql_engine = create_engine('mysql://...')

for engine in [postgres_engine, sqlite_engine, mysql_engine]:
    create_spatial_table(engine)  # Automatically handles differences

Error Handling and Diagnostics

Administrative functions provide comprehensive error handling:

from geoalchemy2.exc import ArgumentError

try:
    # Spatial column with conflicting options
    column = Column(Geometry(use_N_D_index=True, spatial_index=False))
except ArgumentError as e:
    # "spatial_index must be True when use_N_D_index is True"
    print(f"Configuration error: {e}")

# Diagnostic information available
from geoalchemy2.admin.dialects.common import _check_spatial_type

spatial_column = MyTable.geom
is_geometry = _check_spatial_type(spatial_column.type, Geometry)
is_raster = _check_spatial_type(spatial_column.type, Raster)

Performance Optimization

Administrative functions optimize spatial database performance:

Automatic Index Selection

  • PostGIS: Uses GiST indexes for most cases, SP-GiST for points
  • MySQL/MariaDB: Uses R-tree indexes for geometry columns
  • SQLite: Creates virtual spatial index tables via SpatiaLite
  • GeoPackage: Uses built-in R-tree spatial indexing

Memory Management

  • Efficient spatial metadata caching
  • Lazy loading of dialect-specific implementations
  • Minimal overhead for non-spatial operations

Query Optimization

  • Spatial index hints for query planner
  • Dialect-specific query optimizations
  • Automatic spatial operator mapping

Install with Tessl CLI

npx tessl i tessl/pypi-geoalchemy2

docs

database-administration.md

index.md

migration-support.md

shapely-integration.md

spatial-elements.md

spatial-functions.md

spatial-types.md

tile.json