I just wanted to give an update.  I have found a solution that works
ok for now but I had to hack a bit.  I ended up having to use
psycopg2's ability to override how python classes are converted
to/from a database.  psycopg2 seems to have more complete support for
this then SA, so it let me convert to an exact string representation
for my type (ie. GeomFromText('POINT(1 1)') ).  I combined this with
the GeoTypes library to represent geometry types and to read them back
from the OGC binary format.

The relevant code looks like this:

import sqlalchemy as sa
import psycopg2.extensions
import logging
pe = psycopg2.extensions

from GeoTypes import (OGGeoTypeFactory, WKBParser,
                     OGGeometry, OGPoint, OGPolygon, OGLineString)

class PostGisWKBFactory(object):
   def __init__(self):
      pass

   def __call__(self, s=None):
      factory = OGGeoTypeFactory()
      parser = WKBParser(factory)
      parser.parseGeometry(s)
      return factory.getGeometry()


class GeometryType(sa.types.TypeEngine):
   def __init__(self, SRID, typeName, dimension):
      super(GeometryType, self).__init__()
      self.mSrid = SRID
      self.mType = typeName.upper()
      self.mDim  = dimension
      self.bfact = PostGisWKBFactory()

   def __repr__(self):
      return "%s:%s-%s(%s)" % (self.__class__.__name__, self.mType,
self.mDim, self.mSrid)

   def get_col_spec(self):
      return "GEOMETRY"

   def convert_bind_param(self, value, engine):
      # Could be used to make the type _conform_
      #return pe.AsIs(str(value))
      return value

   def convert_result_value(self, value, engine):
      geom_obj = self.bfact(binascii.a2b_hex(value))
      geom_obj._srid = self.mSrid   # set directly
      return geom_obj

class GeometryPOINT(GeometryType):
   def __init__(self, srid):
      super(GeometryPOINT,self).__init__(srid, "POINT", 2)

class GeometryLINESTRING(GeometryType):
   def __init__(self, srid):
      super(GeometryPOINT,self).__init__(srid, "LINESTRING", 2)


Then I added the following method to the GeoTypes.Geometry class to
allow it to represent itself to psycopg2 correctly.

    # Interface to allow psycopg2 to convert to database automatically
    def getquoted(self):
        return self.__str__()

    def __conform__(self, proto):
        # Return ourselves since we have a getquoted method
        return self

I still don't see a way to handle this directly with SA, so if anyone
can tell me a way to let SA know exactly how I want the object's value
to appear in the generated SQL statement please let me know so I can
refine my code.

Thanks,
Allen


On 2/25/07, Allen Bierbaum <[EMAIL PROTECTED]> wrote:
> [snip]
>  > When I use this with my table and datamapper code, it looks like
> > everything is working fine but the generated SQL insert statement
> > fails with a exception:
> >
> > sqlalchemy.exceptions.SQLError: (ProgrammingError) parse error -
> > invalid geometry
> >   'INSERT INTO gis_entity (id, name, pos) VALUES (%(mId)s, %(mName)s,
> > %(mPos)s)' {'mName': 'New entity', 'mId': 1L, 'mPos':
> > "GeomFromText('POINT(100 100)',-1)"}
> >
> > I know from using sql directly in pgadmin3 that this line works correctly:
> >
> > insert into gis_entity (id, name, pos) values (2, 'New entity',
> > GeomFromText('POINT(100 100)', -1));
> >
> > Does anyone see how this varies from the sql statement issued by SA?
>
> By looking at the postgres log I figured out what was causing the
> error, but I still don't know how to fix it.
>
> The problem is that SA considers "GeomFromText('POINT(100 100)', -1)"
> to be a string so it puts it in single quotes when creating the SQL
> command to execute. This causes problems because them postgres doesn't
> know it could be calling a method instead.  I have tried returning an
> sqlalchemy.func object but this doesn't work either.
>
> Any ideas?
>
> -Allen
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to