Search code examples
sqliteweb2pyspatialite

"Adapter does not support geometry" exception when declaring geometry field


In my application, an "Adapter does not support geometry" exception is being thrown when attempting to create a field of type, "geometry()". For my test application, I'm using an sqlite DB (production will use postgres):

db = DAL('sqlite://storage.sqlite', pool_size = 1, fake_migrate_all= False)

The DB table in question is declared within a class, inside of a module, and contains a several fields, some of which contain location data:

from gluon.dal import Field, geoPoint, geoLine, geoPolygon

class Info(Base_Model):

    def __init__(...):

        try: 
            db.define_table('t_info', 
                ...
                Field('f_geolocation', type='geometry()', 
                    label =  current.T('Geolocation')),
                Field('f_city', type='string', 
                    label = current.T('City')),
                ...
        except Exception as e:
            ...

Edit:

As per Anthony's suggestion, I've modified the DAL constructor call to the following:

db = DAL('spatialite://storage.sqlite', pool_size = 1)

It produces the following error message:

Traceback (most recent call last):
  File "C:\...\web2py\gluon\restricted.py", line 227, in restricted
    exec ccode in environment
  File "C:/My_Stuff/Programs/web2py/applications/Proj/models/db.py", line 38, in <module>
    db = DAL('spatialite://storage.sqlite', pool_size = 1) 
  File "C:\...\web2py\gluon\packages\dal\pydal\base.py", line 171, in __call__
    obj = super(MetaDAL, cls).__call__(*args, **kwargs)
  File "C:\...\web2py\gluon\packages\dal\pydal\base.py", line 457, in __init__
    raise RuntimeError("Failure to connect, tried %d times:\n%s" % (attempts, tb))
RuntimeError: Failure to connect, tried 5 times:
Traceback (most recent call last):
  File "C:\...\web2py\gluon\packages\dal\pydal\base.py", line 435, in __init__
    self._adapter = ADAPTERS[self._dbname](**kwargs)
  File "C:\...\web2py\gluon\packages\dal\pydal\adapters\base.py", line 53, in __call__
    obj = super(AdapterMeta, cls).__call__(*args, **kwargs)
  File "C:\...\web2py\gluon\packages\dal\pydal\adapters\sqlite.py", line 169, in __init__
    if do_connect: self.reconnect()
  File "C:\...\web2py\gluon\packages\dal\pydal\connection.py", line 129, in reconnect
    self.after_connection_hook()
  File "C:\...\web2py\gluon\packages\dal\pydal\connection.py", line 81, in after_connection_hook
    self.after_connection()
  File "C:\...\web2py\gluon\packages\dal\pydal\adapters\sqlite.py", line 177, in after_connection
    self.execute(r'SELECT load_extension("%s");' % libspatialite)
  File "C:\...\web2py\gluon\packages\dal\pydal\adapters\base.py", line 1326, in execute
    return self.log_execute(*a, **b)
  File "C:\...\web2py\gluon\packages\dal\pydal\adapters\base.py", line 1320, in log_execute
    ret = self.cursor.execute(command, *a[1:], **b)
OperationalError: The specified module could not be found.

Solution

  • If you want to use geometry fields with SQLite, you must use the spatialite adapter, which makes use of the SpatialLite extension for SQLite:

    db = DAL('spatialite://storage.sqlite', pool_size = 1)
    

    Note, you must have spatialite installed for this to work.