Skip to content

Commit 458cf05

Browse files
committed
Add an example of setting a codec for PostGIS types.
Thanks to Adam Rothman (@adamrothman) for providing this. Closes: #245
1 parent a3b4066 commit 458cf05

File tree

1 file changed

+67
-8
lines changed

1 file changed

+67
-8
lines changed

docs/usage.rst

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ and user-defined types using the :meth:`Connection.set_type_codec() \
166166
<asyncpg.connection.Connection.set_type_codec>` and
167167
:meth:`Connection.set_builtin_type_codec() \
168168
<asyncpg.connection.Connection.set_builtin_type_codec>` methods.
169+
170+
171+
Example: automatic JSON conversion
172+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
173+
169174
The example below shows how to configure asyncpg to encode and decode
170175
JSON values using the :mod:`json <python:json>` module.
171176

@@ -177,17 +182,13 @@ JSON values using the :mod:`json <python:json>` module.
177182
178183
179184
async def main():
180-
conn = await asyncpg.connect('postgresql://postgres@localhost/test')
185+
conn = await asyncpg.connect()
181186
182187
try:
183-
def _encoder(value):
184-
return json.dumps(value)
185-
186-
def _decoder(value):
187-
return json.loads(value)
188-
189188
await conn.set_type_codec(
190-
'json', encoder=_encoder, decoder=_decoder,
189+
'json',
190+
encoder=json.dumps,
191+
decoder=json.loads,
191192
schema='pg_catalog'
192193
)
193194
@@ -200,6 +201,64 @@ JSON values using the :mod:`json <python:json>` module.
200201
asyncio.get_event_loop().run_until_complete(main())
201202
202203
204+
Example: automatic conversion of PostGIS types
205+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
206+
207+
The example below shows how to configure asyncpg to encode and decode
208+
the PostGIS ``geometry`` type. It works for any Python object that
209+
conforms to the `geo interface specification`_ and relies on Shapely_,
210+
although any library that supports reading and writing the WKB format
211+
will work.
212+
213+
.. _Shapely: https://github.com/Toblerity/Shapely
214+
.. _geo interface specification: https://gist.github.com/sgillies/2217756
215+
216+
.. code-block:: python
217+
218+
import asyncio
219+
import asyncpg
220+
221+
import shapely.geometry
222+
import shapely.wkb
223+
from shapely.geometry.base import BaseGeometry
224+
225+
226+
async def main():
227+
conn = await asyncpg.connect()
228+
229+
try:
230+
def encode_geometry(geometry):
231+
if not hasattr(geometry, '__geo_interface__'):
232+
raise TypeError('{g} does not conform to '
233+
'the geo interface'.format(g=geometry))
234+
shape = shapely.geometry.asShape(geometry)
235+
return shapely.wkb.dumps(shape)
236+
237+
def decode_geometry(wkb):
238+
return shapely.wkb.loads(wkb)
239+
240+
await conn.set_type_codec(
241+
'geometry', # also works for 'geography'
242+
encoder=encode_geometry,
243+
decoder=decode_geometry,
244+
format='binary',
245+
)
246+
247+
data = shapely.geometry.Point(-73.985661, 40.748447)
248+
res = await conn.fetchrow(
249+
'''SELECT 'Empire State Building' AS name,
250+
$1::geometry AS coordinates
251+
''',
252+
data)
253+
254+
print(res)
255+
256+
finally:
257+
await conn.close()
258+
259+
asyncio.get_event_loop().run_until_complete(main())
260+
261+
203262
Transactions
204263
------------
205264

0 commit comments

Comments
 (0)