I tried your idea but it doesn't seem to be valid code. Here is the code I tried:
print "Trying with a transaction." conn = db.connect() trans = conn.begin() conn.execute(sa.func.AddGeometryColumn('','gis_entity','fpos',-1,'LINESTRING',2)) trans.commit() conn.close() and here is the exception I get on the execute line: Try with a transaction. INFO:sqlalchemy.engine.base.Engine.0x..d0:BEGIN Traceback (most recent call last): File "gis_type_test.py", line 73, in ? conn.execute(sa.func.AddGeometryColumn('','gis_entity','fpos',-1,'LINESTRING',2, engine=db)) File "/usr/lib/python2.4/site-packages/sqlalchemy/engine/base.py", line 258, in execute return Connection.executors[type(object).__mro__[-2]](self, object, *multiparams, **params) KeyError: <class 'sqlalchemy.sql._CompareMixin'> I am now running into a new problem as well though. I can use my previous hack to insert the column but I can't add data to it because I have been unable to call "GeomFromText(..)" on the insert. I tried to get this working by defining my own type: 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 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): return 'GeomFromText(\'%s\',%s)'%(value, self.mSrid) def convert_result_value(self, value, engine): # Not used yet return value 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? I have stared at it for 20 minutes and I don't see a difference. Is there any way to see the raw SQL statement sent by SA to postgres? I have turned up the debug output level to full but I still only can see the format string and parameters used for making the sql statement: INFO:sqlalchemy.engine.base.Engine.0x..50:INSERT INTO gis_entity (id, name, pos) VALUES (%(mId)s, %(mName)s, %(mPos)s) INFO:sqlalchemy.engine.base.Engine.0x..50:{'mName': 'New entity', 'mId': 1L, 'mPos': "GeomFromText('POINT(100 100)',-1)"} Does anyone see what I am doing wrong here? Once I get this working, then I have to figure out how to get the data back out from postgis. What I want to end up with here is an SQL statement like this: select id, name, AsText(pos) as pos from gis_entity; Note that pos is retrieved through a server side function ('AsText') that unpacks the binary representation from the database into a string representation. Is there any way to do this with SA so the system will always create queries in this form whenever it tries to retrieve the value of pos? I don't know if this makes a solution easier, but I am using mappers for all my tables. What I would really like to have is a mapper that would just automatically know to wrap all references to "pos" in INSERT calls with a call to the server-side function 'GeomFromText' and correspondingly wrap all references to "pos" in SELECT calls with a call to the server-side function 'AsText'. Is it possible to do this at the mapper level? If it is, then that could greatly simplify everything I am trying to do here. Thanks for you help. -Allen On 2/25/07, Michael Bayer <[EMAIL PROTECTED]> wrote: > > if the function youre calling needs a transaction commit, why dont > you call an explicit transaction ? > > conn = engine.connect() > trans = conn.begin() > conn.execute(func.AddGeometryColumn > ('','gis_entity','fpos',-1,'LINESTRING',2)) > trans.commit() > > > On Feb 25, 2007, at 11:02 AM, Allen Bierbaum wrote: > > > > > I have been pursuing this further on my own and one of the issues I > > have run into is how to cleanly add a geometry column to a database. > > The posting referenced in the first e-mail [2] talks about doing this > > directly with psycopg2 cursor because the poster could not get it > > working with SA. I gave it another try to see if I could get it > > working and I think I have narrowed down the problem. That said, I > > still don't fully understand how to fix it with SA only. > > > > Here is my code example: > > > > ---------------------------- > > db = sa.create_engine(dsn_str) > > > > # Option 1: Try using a function on the database (doesn't work) > > print "Run with func" > > db.func.AddGeometryColumn('','gis_entity','fpos',-1,'LINESTRING', > > 2).execute() > > > > # Option 2: Try directly with database statement execution (doesn't > > work) > > print "Run on db" > > r = db.execute("select > > AddGeometryColumn('','gis_entity','cpos',-1,'LINESTRING',2)") > > r.close() > > > > # Option 3: use psycopg to execute directly without autocomit? (works) > > print "Run with psycopg isolation level" > > con = db.connect() > > con.connection.connection.set_isolation_level > > (psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) > > con.execute("select > > AddGeometryColumn('','gis_entity','p_pos',-1,'LINESTRING',2)") > > con.close() > > ------------------------ > > > > > > So option 3 works, but I don't fully understand why it works and why I > > can't use one of the other options. Option 1 is definitely my > > preferred way to do this because it will make the calls look like > > normal SA calls to a DB function. > > > > Can anyone tell my whey option 3 is working and if there is a way to > > do this directly with SA only? > > > > Thanks, > > Allen > > > > > > On 2/23/07, Allen <[EMAIL PROTECTED]> wrote: > >> > >> I would like to use SqlAlchemy with PostGIS to create, read, update, > >> and query spatial data. I have search around a bit and found a few > >> ideas of doing this [1][2] but I haven't seen a definitive best > >> practice by any means. It looks like all the solutions I can find > >> have a least some limitations. > >> > >> Is anyone here using SqlAlchemy with spatial databases and if so how > >> are you doing it right now? > >> > >> Specifically: > >> - How do you handle table specification with geometry types? > >> [1] tries to do this but it is incomplete > >> > >> - Do you use custom types and if so how are you doing this? > >> [2] has some custom type code but it seems to be tied to binary > >> formats and I don't see how to create/retrieve the geometry in text > >> format. > >> > >> - How are you handling the object mapping? > >> For example is there a way to map a "POINT" geometry to a python > >> Point > >> class or tuple? > >> > >> - Do you have any general recommendations for how to use spatial data > >> successfully with SqlAlchemy? > >> > >> > >> Thanks, > >> Allen > >> > >> [1] http://www.mail-archive.com/sqlalchemy- > >> [EMAIL PROTECTED]/msg03371.html > >> [2] http://bycycle.org/2007/01/29/using-postgis-with-sqlalchemy/ > >> > >> > >>> > >> > > > > > > > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com 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 -~----------~----~----~----~------~----~------~--~---