Creating a custom field that automatically converts between db types and python types
See original GitHub issueI want to use Peewee to manage a collection of GIS data. I’ve defined some custom fields to handle the PostGIS geometry
type:
class GeomField(Field):
db_field = 'geometry'
def __init__(self, geom_type=None, geom_srid=None, **kwargs):
self.geom_srid = geom_srid
self.geom_type = geom_type
super(GeomField, self).__init__(**kwargs)
if geom_type:
if geom_srid:
self.db_field = 'geometry(%s, %s)' % (geom_type, geom_srid)
else:
self.db_field = 'geometry(%s)' % (geom_type, )
class PointField(GeomField):
def __init__(self, geom_srid=None, **kwargs):
super(PointField, self).__init__(
geom_type='Point',
geom_srid=geom_srid,
**kwargs)
This works fine so far. I would like to be able to set a PointField
to a Python tuple and have it converted automatically to a geometry
value (and I want the inverse as well). I started with this:
def db_value(self, value):
return fn.st_setsrid(
fn.st_makepoint(value[0],value[1],self.geom_srid))
But I guess that Peewee doesn’t interpolate these functions at the right point, because that gets me:
ValueError: only bytes values expected, got Func
So instead I’ve done this:
def python_value(self, value):
res = database.execute_sql('select st_x(%s), st_y(%s)',
(value, value))
return res.fetchone()
def db_value(self, value):
res = database.execute_sql(
'select st_setsrid(st_makepoint(%s,%s), %s)',
(value[0], value[1], self.geom_srid))
return res.fetchone()
This works, but it seems less than elegant and I am curious if I am missing a simpler solution.
Issue Analytics
- State:
- Created 8 years ago
- Comments:12 (5 by maintainers)
Top Results From Across the Web
How to create custom model fields - Django documentation
Writing a custom field can be a tricky process, particularly if you're doing complex conversions between your Python types and your database and...
Read more >Adapting and Converting SQLite Data Types for Python
This tutorial will explain all the methods the sqlite3 module provides for converting and adapting Python data types into SQLite types, ...
Read more >Custom Types - SQLAlchemy 1.4 Documentation
The TypeDecorator allows the creation of custom types which add bind-parameter and result-processing behavior to an existing type object. It is ...
Read more >Models and Fields — peewee 3.15.4 documentation
It's easy to create custom field types and use them with your models. ... a value coming from the database and converts it...
Read more >The database abstraction layer - Web2py
Web2py's auto-execution of Python code inside the model directory does ... If a field has changed type but not name, it will try...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@coleifer is there a way to override the fn called when performing a read?
IE, instead of
You could specify a wrapper fn for a field, so you could so something like
which would alleviate a lot of the trouble here (I too am trying to figure out how to read/write a simple
geometry(Point)
field with postgis.This appears to create the same outcome as @nbolten , and allows the containment to be on the field itself. It is unclear to me whether _returning is only those fields selected by the select() method, and how this will affect performance in more complex queries. Posting here, though.