django/django · error · Exception

Could not find a geometry column for "%s"."%s"

Error message

Could not find a geometry column for "%s"."%s"

What it means

Generic Exception raised in SpatiaLiteIntrospection.get_geometry_type when a row for (table_name, description.name) is absent from the geometry_columns table. Django introspects an existing table as a geometry field (via data_types_reverse) but the spatial metadata registry has no entry for that column, so it cannot recover srid/dimension/type.

Source

Thrown at django/contrib/gis/db/backends/spatialite/introspection.py:40

        "geometrycollection": "GeometryField",
    }


class SpatiaLiteIntrospection(DatabaseIntrospection):
    data_types_reverse = GeoFlexibleFieldLookupDict()

    def get_geometry_type(self, table_name, description):
        with self.connection.cursor() as cursor:
            # Querying the `geometry_columns` table to get additional metadata.
            cursor.execute(
                "SELECT coord_dimension, srid, geometry_type "
                "FROM geometry_columns "
                "WHERE f_table_name=%s AND f_geometry_column=%s",
                (table_name, description.name),
            )
            row = cursor.fetchone()
            if not row:
                raise Exception(
                    'Could not find a geometry column for "%s"."%s"'
                    % (table_name, description.name)
                )

            # OGRGeomType does not require GDAL and makes it easy to convert
            # from OGC geom type name to Django field.
            ogr_type = row[2]
            if isinstance(ogr_type, int) and ogr_type > 1000:
                # SpatiaLite uses SFSQL 1.2 offsets 1000 (Z), 2000 (M), and
                # 3000 (ZM) to indicate the presence of higher dimensional
                # coordinates (M not yet supported by Django).
                ogr_type = ogr_type % 1000 + OGRGeomType.wkb25bit
            field_type = OGRGeomType(ogr_type).django

            # Getting any GeometryField keyword arguments that are not the
            # default.
            dim = row[0]
            srid = row[1]

View on GitHub (pinned to ae25a40be0)

Solutions

  1. Register the column properly: `SELECT AddGeometryColumn('table','column', srid, 'POINT', 'XY');` so geometry_columns contains the row.
  2. Run InitSpatialMetaData on the database if geometry_columns itself is empty (see prepare_database).
  3. Skip introspection for that table and hand-write the model with the correct GeometryField subclass.
  4. Confirm the column name and table name in the error match a real geometry column in `SELECT * FROM geometry_columns;`.

Example fix

-- before: column exists but is unregistered
ALTER TABLE my_table ADD COLUMN geom POINT;  -- not a real spatial column
-- after: register via SpatiaLite so introspection finds it
SELECT AddGeometryColumn('my_table', 'geom', 4326, 'POINT', 'XY');
Defensive patterns

Strategy: validation

Validate before calling

# pre-introspection sanity: ensure geometry_columns has the row
from django.db import connection
with connection.cursor() as c:
    c.execute("SELECT 1 FROM geometry_columns WHERE f_table_name=%s AND f_geometry_column=%s", (table, col))
    if not c.fetchone():
        raise RuntimeError(f'register column: SELECT AddGeometryColumn(\'{table}\',\'{col}\',4326,\'POINT\',\'XY\')')

Type guard

def geometry_column_registered(table: str, col: str) -> bool:
    from django.db import connection
    with connection.cursor() as c:
        c.execute('SELECT 1 FROM geometry_columns WHERE f_table_name=%s AND f_geometry_column=%s', (table, col))
        return c.fetchone() is not None

Try / catch

from django.contrib.gis.db.backends.spatialite.introspection import SpatiaLiteIntrospection
try:
    field_type, params = introspection.get_geometry_type(table, desc)
except Exception:
    # register the column via AddGeometryColumn or hand-write the model
    ...

Prevention

When it happens

Trigger: Triggered by inspectdb, migrations introspection, or any introspection call on a table whose SQLite type was a geometry type but which was created outside SpatiaLite (raw SQL without AddGeometryColumn / no entry in geometry_columns).

Common situations: A table created via raw DDL using a geometry-named column type; the geometry_columns metadata row was deleted; the DB was partially initialised (InitSpatialMetaData not run); table created with mod_spatialite disabled for that connection.

Related errors


AI-assisted analysis of django/django@ae25a40be0 (2026-08-06). Data as JSON: /api/errors/dae6a352dd2eab2a. Report an issue: GitHub.