GeoAlchemy pg_function.geojson не может быть декодирован с помощью json.loads
Учитывая эту функцию:
features
быть списком объектов SQLAlchemy
template
просто словарь, представляющий шаблон для отображения контента пользователю
def get_feature_dictionary(features, template):
feature_list = []
print features
for feature in features:
for field in template.fields:
if field.data_type == 'geometry':
geometry = getattr(feature, field.name)
geometry_string = db.session.scalar(pg_functions.geojson(getattr(feature, field.name)))
this_feature = {
"type": "Feature",
"geometry": json.loads(geometry_string),
"properties": {
"id": feature.id,
"created": feature.created,
"status": feature.status
}
}
feature_list.append(this_feature)
return feature_list
Я хотел бы вернуть GeoJSON FeatureCollection, которая выглядит следующим образом:
{
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type":"GeometryCollection",
"geometries":[
{"type":"Point","coordinates":[2,0]}
]
},
"properties": {
"created": "Tue, 03 Aug 2010 17:11:13 GMT",
"id": 1,
"status": "public"
},
"type": "Feature"
}
],
"properties": {
"features_per_page": "",
"status": {
"code": 200,
"type": "OK"
},
"total_features": 1021,
"total_pages": ""
}
}
И я могу заставить это распечатать:
{
"type": "FeatureCollection",
"features": [
{
"geometry": '{\"type\":\"GeometryCollection\",\"geometries\":[{\"type\":\"Point\",\"coordinates\":[2,0]},{\"type\":\"Polygon\",\"coordinates\":[[[0,0],[1,0],[1,1],[0,1],[0,0]]]}]}'
],
"properties": {
"features_per_page": "",
"status": {
"code": 200,
"type": "OK"
},
"total_features": 1021,
"total_pages": ""
}
}
Но в итоге я получаю сообщение об ошибке:
TypeError: expected string or buffer
TypeError
TypeError: expected string or buffer
Traceback (most recent call last)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "[--removed--]/modules/api/views.py", line 116, in index
search = get_search_results(feature_type, conditions, FeatureType)
File "[--removed--]/modules/api/search.py", line 499, in get_search_results
data = get_feature_dictionary(search['results'], template)
File "[--removed--]/modules/api/utilities.py", line 241, in get_feature_dictionary
Display the sourcecode for this frameOpen an interactive python shell in this frame"geometry": json.loads(geometry_string),
File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 365, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
TypeError: expected string or buffer
Я пытался изменить тип с помощью str()
но это просто приводит к:
ValueError: No JSON object could be decoded
Я пробовал это с GeoAlchemy (pg_functions.geojson) и GeoAlchemy2 (ST_AsGeoJSON) с одинаковыми результатами. Я знаю, что я близко, но по какой-то причине я не передаю скаляр правильно или что-то в этом роде.
У кого-нибудь есть представление о том, что я делаю не так?
1 ответ
Я обнаружил, что причина, по которой я придумал ValueError: No JSON object could be decoded
ошибка в том, что я не проверял, существует ли значение.
Я изменил это:
geometry_string = db.session.scalar(pg_functions.geojson(getattr(feature, field.name)))
к этому:
geometry_string = db.session.scalar(pg_functions.geojson(getattr(feature, field.name))) or '{}'
и все работало отлично, json.loads()
был спотыкается о пустую строку и не может проанализировать пустую строку как JSON, она как минимум нуждается в пустом объекте JSON {}