How to define a geometry field with Peewee Models

Viewed 363

I have looked at examples online on how to create a geometry field with peewee and this is what I came up with so far:

class GeometryField(Field):
    db_field = 'geometry'

    def db_value(self, value):
        return fn.ST_GeomFromGeoJSON(value)

    def python_value(self, value):
        return fn.ST_AsGeoJSON(value) 

I have added this definition to a table like so:

class GeoJSON(BaseModel):

    geojson_id = UUIDField(primary_key=True, default=uuid.uuid4)
    geometry = GeometryField()

Now, this thing wouldn't run and I don't understand what I missed to make it happen. My aim is to manage insertions of geometric entities into the DB so that later I can make use of PostGIS to query based on locations.

The error I'm getting in the init phase:

peewee.ProgrammingError: syntax error at or near "NOT" LINE 1: ...geojson_id" UUID NOT NULL PRIMARY KEY, "geometry" NOT NULL)

I init the table like so:

        GeoJSON.create_table("geojsons")

What did I miss here? Did I need to do anything else before this geometryfield can be used? Is there a secret geom field that Peewee supports out of the box that I don't know about?

2 Answers

The problem was that the DB failed to install PostGIS and therefore didn't recognize the geometry field from the DB. Once I fixed that and had the extension installed, the solution above worked perfectly.

If you are coming back to this question later. The Peewee Syntax has changed since version 3.0. db_field has changed to field_type.

So to get it working:

  1. Make sure you install the PostGIS extension on your postgres database.
    CREATE EXTENSION postgis;
  2. Create a custom field.
class GeometryField(Field):
    field_type = 'geometry'

    def db_value(self, value):
        return fn.ST_GeomFromGeoJSON(value)

    def python_value(self, value):
        return fn.ST_AsGeoJSON(value) 
  1. Use the custom field in your model
class GeoJSON(BaseModel):
    geojson_id = UUIDField(primary_key=True, default=uuid.uuid4)
    geometry = GeometryField()

Peewee Docs

Related